zoukankan      html  css  js  c++  java
  • JSP自定义标签——传统标签

      同JSP标签一样,自定义标签主要用于移除JSP页面中的Java代码,可以看到我们在JSP中其实是禁止使用Java脚本的,任何要想通过Java代码实现的功能都必须以标签形式来处理,可以使用JSP标签,JSTL标签,EL函数,或者自定义标签。

      自定义标签分为传统标签和简单标签,简单标签是Sun公司为减低自定义标签技术的学习难度而定义的,对于简单标签请看下一篇博客。本文先来学习传统自定义标签。

      使用传统自定义标签需要满足以下两个步骤:

      ① 编写一个实现Tag接口(实际上我们更常的是继承Tag接口的实现类从而免于覆写所有的方法)的Java类,这个Java类也称为标签处理器类。

      ② 编写标签的TLD文件,用于指定标签的URI和对标签的声明描述,这一点和EL函数时一样的,TLD文件必须放置在web应用下的【WEB-INF】文件中,可以是除【classes】和【lib】目录以外的任何子目录中。TLD文件的模板可以从【Tomcat】--->【webapps】--->【examples】--->【WEB-INF】--->【jsp2】中有一个“jsp2-example-taglib.tld”文件复制首尾和其中的<Tag>标签。

      注:在TLD文件中我们使用<tag>标签来对每一个自定义标签的Java类进行描述,其中每个<tag>标签下还需要指定<body-content>的值,这个是描述标签体的类型:

      对于传统标签使用:“EMPTY”(代表标签没有标签体)或“JSP”(代表标签有标签体)。

      以上的步骤整体类似于我们自定义EL函数,而不同的是这里的Java类需要继承特定的JSP的API中提供的类并覆盖其中特定的方法。

      我们先看一看Tag类的API,注意,这是JSP技术,请看JSP的API:

      

      

      从上面可以看到Tag是一个接口,如果我们直接继承Tag接口的话,那就得覆写这六个方法,那就显得十分麻烦了,况且有些方法是属于标签的生命周期方法,是由JSP引擎调用的,因此我们只需要继承Tag接口的实现子类即可,通常我们使用“TagSupport”类或者“BodyTagSupport”类,能有更多的功能。

      在Tag接口中,除了getParent方法以外,其他都是生命周期方法。在浏览器在解析一个JSP页面时,遇到某个自定义标签后就会开始执行该标签的生命周期方法。自定义标签的生命周期顺序为:① 创建自定义标签的实例对象 ---> ② setPageContext方法 ---> ③ setParent方法---> ④ doStart方法 ---> ⑤ doEnd方法 ---> ⑥ release方法(通常在服务器关闭时才调用)。

      下面简单的介绍下这几个生命周期方法:

      setPageContext方法(重要),JSP引擎对标签进行实例化对象后,会先调用setPageContext方法,将JSP页面的pageContext对象传入这个标签处理器类,我们在JSP的pageContext隐式对象一文中说过,只要拥有了pageContext对象,那么就可以获取其他八大隐式对象从而操作web中的需求了。

      setParent方法,在setPageContext方法执行完之后,将调用setParent方法,这个方法将会把这个自定义标签的父类标签(如果有)传递给该标签处理器类,如果没有父类标签,那么setParent方法的参数即为null。注意,这里说的标签的父标签也是指自定义标签,如果该自定义标签的只是嵌入在普通的HTML标签的话那么就是无父类标签,执行的只是setParent(null)方法。

      doStartTag方法,当JSP引擎接连调用setPageContext方法和setParent方法完成标签的配置之后,当浏览器解析标签的开始标签时,就会调用doStartTag方法。通常我们在使用标签处理某个功能时,就将该功能在doStartTag方法中覆写。另外,依据doStartTag方法的返回值是“EVAL_BODY_INCLUDE”(执行)还是“SKIP_BODY”(不执行)决定是否执行标签体中的内容。可以说这是我们要使用标签来封装Java代码最重要的一个方法。

      doEndTag方法,当浏览器在JSP页面中解析到该标签的结束标签时,就会调用doEndTag方法。另外,依据doEndTag方法的返回值是“EVAL_PAGE”(执行)还是“SKIP_PAGE” (不执行)决定是否执行结束标签之后余下的JSP页面内容。

      release方法,通常JSP调用完doEndTag方法后,并不会立即执行release方法,因为为了服务器的性能,通常就会将标签处理器类的对象驻留于内存中,以便下次能更快速地调用,这一点和Servlet是一样的。一般在停止该web应用或服务器停止时才会调用标签处理器的release方法,释放标签中的资源。

      通常我们使用的是一个Java类继承TagSupport类或者BodyTagSupport类,对于处理标签,依然也是覆写doStartTag方法。同时注意到TagSupport类中,一个属性即为pageContext,注意这是字段,同时能给子类调用(protected修饰),而我们基本在覆写doStartTag方法中要随处用到这个字段:

      

    例1:使用自定义标签来显示来访者IP

      创建一个Java类继承TagSupport类,覆写doStartTag方法,这里因为标签没有标签体,可以暂时不用管doStartTag方法的返回值:

     1 package com.fjdingsd.tag;
     2 public class GuestIpTag extends TagSupport {
     3     @Override
     4     public int doStartTag() throws JspException {
     5         
     6         HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();
     7         String ip = request.getRemoteAddr();
     8         JspWriter out = this.pageContext.getOut();
     9         try {
    10             out.write(ip);
    11         } catch (IOException e) {
    12             throw new RuntimeException(e);
    13         }
    14         return super.doStartTag();
    15     }
    16 }
    View Code

    接着在web应用的【WEB-INF】中创建TLD文件,设置好uri和标签的名称、类、以及标签体类型:

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 
     3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
     4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     5     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
     6     version="2.0">
     7     <description>A tag library exercising SimpleTag handlers.</description>
     8     <tlib-version>1.0</tlib-version>
     9     <short-name>SimpleTagLibrary</short-name>
    10     <uri>selftag</uri>
    11     
    12     <tag>
    13         <name>guestip</name>
    14         <tag-class>com.fjdingsd.tag.GuestIpTag</tag-class>
    15         <body-content>empty</body-content>
    16     </tag>
    17 </taglib>
    View Code

    最后就可以在JSP页面中使用自定义标签了,当然别忘了使用taglib指令先导入我们的标签所在的uri:

        <%@ taglib uri="selftag" prefix="selftag" %>

    在JSP页面的主体中使用我们设计好的自定义标签:

        您的ip地址为:<selftag:guestip/>

    浏览器中观察:

      

    例2:控制标签的标签体内容是否输出显示

             如果要想控制标签体的内容是否输出显示,只需要修改doStartTag方法的返回值即可:

     1 package com.fjdingsd.tag;
     2 public class ShowTagBodyOrNot extends TagSupport {
     3     @Override
     4     public int doStartTag() throws JspException {
     5         HttpSession session = this.pageContext.getSession();
     6         User user = (User) session.getAttribute("user");
     7         if(user==null) {
     8             return TagSupport.SKIP_BODY;  //隐藏标签体内容
     9         }else{
    10             return TagSupport.EVAL_BODY_INCLUDE;  //显示标签体内容
    11         }
    12     }
    13 }
    View Code

    在TLD文件中定义(这里忽略文件首尾其他定义):

    1 <tag>
    2         <name>showbody</name>
    3         <tag-class>com.fjdingsd.tag.ShowTagBodyOrNot</tag-class>
    4         <body-content>JSP</body-content>
    5 </tag>
    View Code

    在JSP页面中导入taglib指令后并在JSP页面主体部分使用自定义标签:

    1     <selftag:showbody>
    2             只有登录用户才能显示……
    3     </selftag:showbody>
    View Code

      当然这个例子当我没有在session域中存入User对象时,是不会在页面上显示这个标签的标签体内容的,这里只是用来强调在doStartTag方法的返回值“EVAL_BODY_INCLUDE”与“SKIP_BODY”的区别。

    例3:控制标签之后余下的JSP页面是否输出显示

      如果要想标签之后余下的JSP页面是否输出显示,只需要修改doEndTag方法的返回值即可:

     1 package com.fjdingsd.tag;
     2 public class ShowJSPOrNot extends TagSupport {
     3     //注意,TagSupport的doStartTag方法默认返回值为SKIP_BODY,也就是不执行标签体内容
     4     @Override
     5     public int doEndTag() throws JspException {
     6         HttpSession session = this.pageContext.getSession();
     7         User user = (User) session.getAttribute("user");
     8         if(user==null) {
     9             return TagSupport.SKIP_PAGE;  隐藏结束标签后余下JSP页面        }else{
    10             return TagSupport.EVAL_PAGE;  //显示结束标签后余下JSP页面
    11         }
    12     }
    13 }
    View Code

    在TLD文件中定义(这里忽略文件首尾其他定义):

    1 <tag>
    2         <name>showpage</name>
    3         <tag-class>com.fjdingsd.tag.ShowJSPOrNot</tag-class>
    4         <body-content>empty</body-content>
    5 </tag>
    View Code

    在JSP页面中导入taglib指令后并在JSP页面主体部分使用自定义标签:

     1 <selftag:showpage/>
     2 
     3 <!DOCTYPE HTML>
     4 <html>
     5       <head>   
     6             <title>My JSP 'demo1.jsp' starting page</title>
     7       </head>
     8   
     9       <body>
    10             。。。
    11     <body>
    12 </html>        
    View Code

      这里我把自定义标签置于JSP页面最开始的地方,可以看到如果没有在session域中存入User对象的话,那么这个JSP在被访问后是不会看到任何东西的,查看网页源码也是没有任何代码。当然这个例子只是用来强调在doEndTag方法的返回值 “EVAL_PAGE”和 “SKIP_PAGE”的区别。

      使用传统的自定义标签还可以扩展一些其他的功能,比如控制标签体的内容重复执行,修改标签体内容再输出等等,这两个功能涉及到使用Tag不同实现类的使用,将在下一篇博客中进行讲解。

       

  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/fjdingsd/p/5118085.html
Copyright © 2011-2022 走看看