zoukankan      html  css  js  c++  java
  • jsp简单标签开发

    一、简单标签(SimpleTag)

      由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。

      

    实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:

    • setJspContext方法
    • setParent和getParent方法
    • setJspBody方法
    • doTag方法(非常重要),简单标签使用这个方法就可以完成所有的业务逻辑

    二、SimpleTag方法介绍

    2.1、setJspContext方法

      用于把JSP页面的pageContext对象传递给标签处理器对象

    2.2、setParent方法

      用于把父标签处理器对象传递给当前标签处理器对象

    2.3、getParent方法

    用于获得当前标签的父标签处理器对象

    2.4、setJspBody方法

      用于把代表标签体的JspFragment对象传递给标签处理器对象

    2.5、doTag方法

      用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

    三、SimpleTag接口方法的执行顺序

      当web容器开始执行标签时,会调用如下方法完成标签的初始化:

    1. WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
    2. WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
    3. 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
    4. 如果简单标签有标签体,WEB容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
    5. 执行标签时WEB容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

    四、开发简单标签实现页面逻辑

      SUN公司针对SimpleTag接口提供了一个默认的实现类SimpleTagSupport,SimpleTagSupport类中实现了SimpleTag接口的所有方法,因此我们可以编写一个类继承SimpleTagSupport类,然后根据业务需要再重写doTag方法。

    4.1、控制jsp页面某一部分内容是否执行

     编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面不调用jspFrament.invoke方法即可。

    示例代码如下:

    SimpleTagDemo1.java

    复制代码
     1 package me.gacl.web.simpletag;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.jsp.JspException;
     6 import javax.servlet.jsp.PageContext;
     7 import javax.servlet.jsp.tagext.JspFragment;
     8 import javax.servlet.jsp.tagext.SimpleTagSupport;
     9 
    10 /**
    11  * @author gacl
    12  * SimpleTagSupport类实现了SimpleTag接口,
    13  * SampleTagDemo1类继承SimpleTagSupport
    14  */
    15 public class SimpleTagDemo1 extends SimpleTagSupport {
    16 
    17     /* 简单标签使用这个方法就可以完成所有的业务逻辑
    18      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
    19      * 重写doTag方法,控制标签体是否执行
    20      */
    21     @Override
    22     public void doTag() throws JspException, IOException {
    23         //得到代表jsp标签体的JspFragment
    24         JspFragment jspFragment = this.getJspBody();
    25         
    26         //得到jsp页面的的PageContext对象
    27         //PageContext pageContext = (PageContext) jspFragment.getJspContext();
    28         //调用JspWriter将标签体的内容输出到浏览器
    29         //jspFragment.invoke(pageContext.getOut());
    30         
    31         //将标签体的内容输出到浏览器
    32         jspFragment.invoke(null);
    33         
    34     }
    35 }
    复制代码

      在WEB-INF目录下新建一个simpletag.tld文件,然后在simpletag.tld文件中添加对该标签处理类的描述,如下:

      

      simpletag.tld文件代码如下:

    复制代码
     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用来添加对taglib(标签库)的描述 -->
     8     <description>孤傲苍狼开发的SimpleTag自定义标签库</description>
     9     <!--taglib(标签库)的版本号 -->
    10     <tlib-version>1.0</tlib-version>
    11     <short-name>GaclSimpleTagLibrary</short-name>
    12     <!-- 
    13         为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/simpletag ,
    14         在Jsp页面中引用标签库时,需要通过uri找到标签库
    15         在Jsp页面中就要这样引入标签库:<%@taglib uri="/simpletag" prefix="gacl"%>
    16     -->
    17     <uri>/simpletag</uri>
    18     
    19     <!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述  -->
    20     <!-- 一个tag标记对应一个自定义标签 -->
    21      <tag>
    22         <description>SimpleTag(简单标签)Demo1</description>
    23         <!-- 
    24             为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类的
    25             通过demo1就能找到对应的me.gacl.web.simpletag.SimpleTagDemo1类
    26          -->
    27         <name>demo1</name>
    28         <!-- 标签对应的处理器类-->
    29         <tag-class>me.gacl.web.simpletag.SimpleTagDemo1</tag-class>
    30         <!-- 
    31         tld文件中有四种标签体类型 :empty  JSP  scriptless  tagdepentend  
    32             在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
    33             在传统标签中标签体body-content的值只允许是empty和JSP
    34             如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
    35             例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
    36             <gacl:sql>SELECT * FROM USER</gacl:sql>
    37             在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可
    38         -->
    39         <body-content>scriptless</body-content>
    40     </tag>
    41 </taglib>
    复制代码

      在jsp页面中导入并使用自定义标签,如下:

    复制代码
     1 <%@ page language="java" pageEncoding="UTF-8"%>
     2 <%--在jsp页面中导入自定义标签库 --%>
     3 <%@taglib uri="/simpletag" prefix="gacl" %>
     4 <!DOCTYPE HTML>
     5 <html>
     6   <head>
     7     <title>用简单标签控制标签体是否执行</title>
     8   </head>
     9   
    10   <body>
    11   
    12   <%--在jsp页面中使用自定义标签 demo1标签是带有标签体的,标签体的内容是"孤傲苍狼"这几个字符串--%>
    13     <gacl:demo1>
    14         孤傲苍狼
    15     </gacl:demo1>
    16   </body>
    17 </html>
    复制代码

      运行效果如下:

      

    4.2、控制jsp页面内容重复执行

      编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面重复调用jspFrament.invoke方法即可。

    示例代码如下:

    SimpleTagDemo2.java

    复制代码
     1 package me.gacl.web.simpletag;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.jsp.JspException;
     6 import javax.servlet.jsp.tagext.JspFragment;
     7 import javax.servlet.jsp.tagext.SimpleTagSupport;
     8 
     9 /**
    10  * @author gacl
    11  * SimpleTagSupport类实现了SimpleTag接口,
    12  * SampleTagDemo2类继承SimpleTagSupport
    13  */
    14 public class SimpleTagDemo2 extends SimpleTagSupport {
    15 
    16     /* 简单标签使用这个方法就可以完成所有的业务逻辑
    17      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
    18      * 重写doTag方法,控制标签执行5次
    19      */
    20     @Override
    21     public void doTag() throws JspException, IOException {
    22         // 得到代表jsp标签体的JspFragment
    23         JspFragment jspFragment = this.getJspBody();
    24         for (int i = 0; i < 5; i++) {
    25             // 将标签体的内容输出到浏览器
    26             jspFragment.invoke(null);
    27         }
    28     }
    29 }
    复制代码

      在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:

    复制代码
    1 <tag>
    2         <!-- 标签名 -->
    3         <name>demo2</name>
    4         <!-- 标签处理器类-->
    5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class>
    6         <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码-->
    7         <body-content>scriptless</body-content>
    8 </tag>
    复制代码

      在jsp页面中导入并使用自定义标签,如下:

    复制代码
     1 <%@ page language="java" pageEncoding="UTF-8"%>
     2 <%--在jsp页面中导入自定义标签库 --%>
     3 <%@taglib uri="/simpletag" prefix="gacl" %>
     4 <!DOCTYPE HTML>
     5 <html>
     6   <head>
     7     <title>用简单标签控制标签体执行5次</title>
     8   </head>
     9   
    10   <body>
    11   
    12   <%--在jsp页面中使用自定义标签 --%>
    13     <gacl:demo2>
    14         孤傲苍狼<p/>
    15     </gacl:demo2>
    16   </body>
    17 </html>
    复制代码

      运行效果如下:

      

    4.3、修改jsp页面内容输出

      编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法调用jspFrament.invoke方法时,让执行结果写一个自定义的缓冲中即可,然后开发人员可以取出缓冲的数据修改输出。

    示例代码如下:

    SimpleTagDemo3.java

    复制代码
     1 package me.gacl.web.simpletag;
     2 
     3 import java.io.IOException;
     4 import java.io.StringWriter;
     5 
     6 import javax.servlet.jsp.JspException;
     7 import javax.servlet.jsp.PageContext;
     8 import javax.servlet.jsp.tagext.JspFragment;
     9 import javax.servlet.jsp.tagext.SimpleTagSupport;
    10 
    11 /**
    12  * @author gacl
    13  * SimpleTagSupport类实现了SimpleTag接口,
    14  * SampleTagDemo3类继承SimpleTagSupport
    15  */
    16 public class SimpleTagDemo3 extends SimpleTagSupport {
    17 
    18     /* 简单标签使用这个方法就可以完成所有的业务逻辑
    19      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
    20      * 重写doTag方法,修改标签体里面的内容,将标签体的内容转换成大写
    21      */
    22     @Override
    23     public void doTag() throws JspException, IOException {
    24         // 得到代表jsp标签体的JspFragment
    25         JspFragment jspFragment = this.getJspBody();
    26         StringWriter sw = new StringWriter();
    27         //将标签体的内容写入到sw流中
    28         jspFragment.invoke(sw);
    29         //获取sw流缓冲区的内容
    30         String content = sw.getBuffer().toString();
    31         content = content.toUpperCase();
    32         PageContext pageContext = (PageContext) this.getJspContext();
    33         //将修改后的content输出到浏览器中
    34         pageContext.getOut().write(content);
    35     }
    36 }
    复制代码

      在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:

    复制代码
    1 <tag>
    2         <!-- 标签名 -->
    3         <name>demo3</name>
    4         <!-- 标签处理器类-->
    5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo3</tag-class>
    6         <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码-->
    7         <body-content>scriptless</body-content>
    8 </tag>
    复制代码

      在jsp页面中导入并使用自定义标签,如下:

    复制代码
     1 <%@ page language="java" pageEncoding="UTF-8"%>
     2 <%--在jsp页面中导入自定义标签库 --%>
     3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%>
     4 <%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录 --%>
     5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%>
     6 <!DOCTYPE HTML>
     7 <html>
     8   <head>
     9     <title>用简单标签修改jsp页面内容输出</title>
    10   </head>
    11   
    12   <body>
    13   
    14   <%--在jsp页面中使用自定义标签 --%>
    15     <gacl:demo3>
    16         gacl_xdp
    17     </gacl:demo3>
    18   </body>
    19 </html>
    复制代码

      运行效果如下:

      

    4.4、控制整个jsp页面是否执行

      编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法抛出SkipPageException异常即可,jsp收到这个异常,将忽略标签余下jsp页面的执行。

    示例代码如下:

    SimpleTagDemo4.java

    复制代码
     1 package me.gacl.web.simpletag;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.jsp.JspException;
     5 import javax.servlet.jsp.SkipPageException;
     6 import javax.servlet.jsp.tagext.SimpleTagSupport;
     7 
     8 /**
     9  * @author gacl
    10  * SimpleTagSupport类实现了SimpleTag接口,
    11  * SampleTagDemo4类继承SimpleTagSupport
    12  */
    13 public class SimpleTagDemo4 extends SimpleTagSupport {
    14 
    15     /* 简单标签使用这个方法就可以完成所有的业务逻辑
    16      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
    17      * 重写doTag方法,控制标签余下的Jsp不执行
    18      */
    19     @Override
    20     public void doTag() throws JspException, IOException {
    21         //抛出一个SkipPageException异常就可以控制标签余下的Jsp不执行
    22         throw new SkipPageException();
    23     }
    24 }
    复制代码

      在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:

    复制代码
    1 <tag>
    2         <!-- 标签名 -->
    3         <name>demo4</name>
    4         <!-- 标签处理器类-->
    5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo4</tag-class>
    6         <!-- 标签体允许的内容 ,empty表示该标签没有标签体-->
    7         <body-content>empty</body-content>
    8 </tag>
    复制代码

      在jsp页面中导入并使用自定义标签,如下:

    复制代码
     1 <%@ page language="java" pageEncoding="UTF-8"%>
     2 <%--在jsp页面中导入自定义标签库 --%>
     3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%>
     4 <%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录 --%>
     5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%>
     6 <!DOCTYPE HTML>
     7 <html>
     8   <head>
     9     <title>用简单标签控制标签余下的Jsp不执行</title>
    10   </head>
    11 
    12   <body>
    13       <h1>孤傲苍狼</h1>
    14        <%--在jsp页面中使用自定义标签 --%>
    15        <gacl:demo4/>
    16        <!-- 这里的内容位于 <gacl:demo4/>标签后面,因此不会输出到页面上 -->
    17        <h1>白虎神皇</h1>
    18   </body>
    19 </html>
    复制代码

      运行效果如下:

      

    五、简单标签开发的一些注意细节

    5.1、标签类编写细节

      开发标签类时,不要直接去实现SimpleTag接口,而是应该继承SimpleTagSupport类,SimpleTagSupport类是SimpleTag接口的一个默认实现类,通过继承SimpleTagSupport类,就可以直接使用SimpleTagSupport类已经实现的那些方法,如果SimpleTagSupport类的方法实现不满足业务要求,那么就可以根据具体的业务情况将相应的方法进行重写。

    5.2、tld文件中标签体类型设置细节

      我们开发好一个简单标签后,需要在tld文件中添加对该标签的描述,例如:

    复制代码
    1 <tag>
    2         <!-- 标签名 -->
    3         <name>demo2</name>
    4         <!-- 标签处理器类-->
    5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class>
    6         <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码-->
    7         <body-content>scriptless</body-content>
    8 </tag>
    复制代码

      开发好一个标签后,在tld文件中使用<tag>来描述一个标签,描述的内容包括标签名(name),标签处理器类(tag-class),标签体的内容(body-content)。

      tld文件中有四种标签体(body-content)类型 :empty、JSP、scriptless、tagdependent 

    简单标签标签体的细节注意问题:
         在简单标签(SampleTag)中标签体body-content的值只允许是empty、scriptless、tagdependent,不允许设置成JSP,如果设置成JSP就会出现异常

    1 The TLD for the class me.gacl.web.simpletag.SimpleTagDemo1 specifies an invalid body-content (JSP) for a SimpleTag

      body-content的值如果设置成empty,那么就表示该标签没有标签体,如果是设置成scriptless,那么表示该标签是有标签体的,但是标签体中的内容不可以是<%java代码%>,例如:

    复制代码
    1 <gacl:xdpdemo1>
    2    <%
    3            //嵌套在标签体中的java代码
    4         int i= 0;
    5     %>
    6       孤傲苍狼
    7 </gacl:xdpdemo1>
    复制代码

      否则运行标签时就会出现如下错误:

    1 Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here

      jsp标签技术出现的目的就是为了移除在jsp页面上编写的java代码的,如果在jsp标签中允许出现java代码,那么就违背了jsp标签技术设计时的初衷了。所以在简单标签的标签体中是不允许出现java代码的。

    传统标签标签体的细节注意问题:
         在传统标签中标签体body-content的值允许是empty、JSP、scriptless、tagdependentbody-content的值如果是设置成JSP那么表示该标签是有标签体的,并且标签体的内容可以是任意的,包括java代码,如果是设置成scriptless那么表示该标签是有标签体的,但是标签体的内容不能是java代码
        

      如果传统标签简单标签的标签体body-content的值设置成tagdependent,那么就表示标签体里面的内容是给标签处理器类使用的,tagdependent用得比较少,了解一下即可

    5.3、tld文件中标签库的uri设置细节

      如果在一个项目中使用或者开发了多个标签库,例如:

      

      那么标签库的uri不能设置成相同的,否则在Jsp页面中通过uri引用标签库时就不知道引用哪一个标签库了,如果真的有那么巧,两个标签库的uri是刚好一样的,如下图所示:

      

      那么在jsp页面中引用标签库时如果"<%@taglib uri="/gacl" prefix="gacl" %>"这样引用,那么就无法判断当前引用的标签库到底是gacl.tld标签库中的标签还是simpletag.tld标签库中的标签,因为两个标签库的uri刚好都是"/gacl",在两个标签库的引用uri一样的情况下,为了能够在jsp中区别到底引用的是哪个标签库,可以换一种引用方式:<%@taglib uri="要引用的标签库的tld文件目录" prefix="gacl"%>,使用taglib指令引入标签库时,taglib指令的uri属性指定为标签库的tld文件目录,这样就可以区别开了,例如:

      引用gacl.tld标签库:<%@taglib uri="/WEB-INF/gacl.tld" prefix="gacl"%>、

      引用simpletag.tld标签库:<%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%>

      所以当在项目中引用了多个标签库,如果标签库的uri刚好是一样的,就可以用这种方式解决。

    六、简单标签开发步骤总结

      1、编写一个类继承SimpleTagSupport类,然后根据业务需要重写SimpleTagSupport类中已经实现了的方法,一般情况下只需要重写doTag()方法即可。

      2、在WEB-INF目录下创建一个tld文件,在tld文件中添加对该标签的描述。tld文件不一定放在WEB-INF目录下,也可以放在别的目录,习惯是放在WEB-INF目录下。

  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8367669.html
Copyright © 2011-2022 走看看