[个人博客搬运]JavaEE自定义标签技术

来源:互联网 发布:艺恩数据 电视剧网播 编辑:程序博客网 时间:2024/06/05 19:00

我们经常用到的JSTL(JSP标签标准库)是典型的自定义标签的案例。

自定义标签,即是在JSP页面的标签中自定义它们的功能,因为在MVC和三层架构中,JSP页面作为视图(view)是不允许出现Java代码的,一旦迫不得已要写Java代码,我们可以将其用自定义标签移除。

而且主流框架如Struts2等也使用了自己的一套自定义标签,学习自定义标签有利于对框架源码的理解。

自定义标签有两种实现方式:

  一是实现Tag或IterationTag接口,或者继承TagSupport类,但是这种方法接口太多不统一,JSP2.0后不再使用,但是主流框架的源码仍然使用这种方式

  二是实现SimpleTag接口,或继承SimpleTagSupport类,这个类是sun公司后来重新统一接口设计的实现类。

本文简单介绍两种方式。(资料参考传智播客,在此感谢)

场景是:使标签体的内容输出5次。

方式一:

1.首先编写一个实现Tag接口或者继承TagSupport实现类的Java类(称为标签处理器类):

 1 package web.tag; 2  3 import javax.servlet.jsp.JspException; 4 import javax.servlet.jsp.tagext.IterationTag; 5 import javax.servlet.jsp.tagext.Tag; 6 import javax.servlet.jsp.tagext.TagSupport; 7  8 public class Repeat extends TagSupport { 9     private int times = 5;10     @Override11      //这个方法调用发生在标签体的开始标签,返回值是一个Tag接口的常量,表示执行标签体(相应的还有不执行标签体,自行查阅API)12     public int doStartTag() throws JspException {13         14         return Tag.EVAL_BODY_INCLUDE;    15     }16     17     @Override18      //这个方法调用发生在标签体执行一次结束,结束标签之前。返回EVAL_BODY_AGAIN表示再执行一次这个方法;返回SKIP_BODY表示跳过标签体19     public int doAfterBody() throws JspException {20         --times;//标签体执行这个方法前会把body执行一遍,所以直接减一次21         if (times > 0) {22             return IterationTag.EVAL_BODY_AGAIN;23         }24         return IterationTag.SKIP_BODY;25     }26 27     28 }

 

2.在tld文件中对标签处理器类进行描述。tld文件本身是一个xml文档,可以参考Tomcat服务器下webapps\examples\WEB-INF\jsp2\jsp2-example-taglib.tld的写法,写一个自己标签的声明,放到/WEB-INF目录下:

<?xml version="1.0" encoding="ISO-8859-1" ?><!DOCTYPE taglibPUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN""http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd"><taglib><tlib-version>1.0</tlib-version><jsp-version>1.2</jsp-version><short-name>simple</short-name><uri>http://localhost:8080</uri>    <!--这里是给tld文件一个标识符,在JSP页面中要引入这个标识符,以便服务器能找到这个tld文件--><tag><name>repeat</name>          <!--这里应该挺好理解的,最后一个body-content可以写JSP(有)、empty(没有标签体)--><tag-class>web.tag.Repeat</tag-class><body-content>JSP</body-content></tag></taglib>

 

 

 


3.在jsp页面中导入uri和使用自定义标签

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri = "http://localhost:8080" prefix = "zzqiltw" %>  <!--这里写上刚才写的uri,后面的prefix可以任意改--><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>使标签体循环5次</title>  </head>  <body>  <zzqiltw:repeat>    这句话会输出五次<br>         <!--使用标签-->      </zzqiltw:repeat>  </body></html>

 

  

方式二:

步骤大同小异,简单说一下:

1.

package web.SimpleTag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class Repeat extends SimpleTagSupport{    @Override  //这个方法相当与传统方式的doStartTag、doEndTag等等方法,全部封装到doTag方法里    public void doTag() throws JspException, IOException {        JspFragment jf = this.getJspBody();    //这里得到整个标签体封装成的JspFragment对象                for (int i = 0; i < 5; ++i) {            jf.invoke(null);//相当于jf.invoke(this.getJspContext().getOut());  调用invoke方法即可        }    }    }

2.

<?xml version="1.0" encoding="ISO-8859-1" ?><!DOCTYPE taglib        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"        "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd"><taglib>  <tlib-version>1.0</tlib-version>  <jsp-version>1.2</jsp-version>  <short-name>simple</short-name>  <uri>http://localhost:8080/simple</uri>       <tag>          <name>repeat</name>          <tag-class>web.SimpleTag.Repeat</tag-class>    <!--scriptless相对于之前的JSP,但是这里sun公司设计成这样,是希望我们不要在jsp里写java代码-->          <body-content>scriptless</body-content>  </tag>    </taglib>  

 3.

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib uri = "http://localhost:8080/simple" prefix = "simple" %> 3  4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 5 <html> 6   <head> 7     <title></title> 8   </head> 9   <body>10   <simple:repeat>11     This is my JSP page. <br>12    </simple:repeat>13   </body>14 </html>

======================

简单的入门就到这里结束了。API文档里的Tag接口和SimpleTag接口里还有几个常量和方法,使用方法里面都介绍得很详尽了,可以自己查阅。

0 0