此文的最终效果是:生成一个select下拉框,里面的值从start到end
1、编写标签的生成定义类
package com.taglib; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class TestTag extends TagSupport { private static final long serialVersionUID = 2598164158273902707L; //下面3个属性对应jsp页面的标签的3个属性 private String name; private String start; private String end; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getEnd() { return end; } public void setEnd(String end) { this.end = end; } public static long getSerialversionuid() { return serialVersionUID; } @Override public int doEndTag() throws JspException { return super.doEndTag(); } @Override public int doStartTag() throws JspException { JspWriter out = this.pageContext.getOut(); int startInt = Integer.parseInt(start); int endInt = Integer.parseInt(end); if(endInt<startInt){ throw new JspException("end must larger start!!"); } try{ out.write("<select name='"); out.write(this.name); out.write("'>"); for(int i=startInt; i<=endInt; i++){ out.write("<option value='"); out.write(String.valueOf(i));//这里如果直接输出int会出现非字符型的string out.write("'>"); out.write(String.valueOf(i)); out.write("</option>"); } out.write("</select>"); }catch (Exception e) { throw new JspException(e); } return super.doStartTag(); } }
2、在web-inf下编写tld定义文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>ytag</short-name> <tag> <name>TestSelectTag</name> <tag-class>com.taglib.TestTag</tag-class> <body-content>empty</body-content> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>start</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>end</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
3、在web.xml中加入定义的标签
<jsp-config> <taglib> <taglib-uri>/yzlTestTag</taglib-uri><!-- 这里定义在uri将在jsp引用该标签时的uri地址 --> <taglib-location>/WEB-INF/yzlTags.tld</taglib-location> </taglib> </jsp-config>
4、在jsp中使用
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/yzlTestTag" prefix="ytag"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> </head> <body> <ytag:TestSelectTag name="myselect" start="1" end="10"/> </body> </html>
注意事项:
特别说明:在tomcat4.1之后的版本中默认开启了标签缓冲池(websphere和weblogic并不会这么做),所以执行完标签后并不会执行release()方法(_jspDestroy()时才释放),也就是说同一个jsp页面自定义标签不管使用多少次只会存在一个实例,但也并不是每一个标签都会为其创建一个缓冲池,要根据参数来判断,例如: <cc:UserInfoTag user=”…” /> <cc:UserInfoTag /> 上面例子中由于参数不同就会创建两个标签缓冲池。 这个问题可以通过设定tomcat的配置文件加以解决: 在%tomcat%\conf\web.xml加入enablePooling参数,并设置为false(不缓存自定义标签)。 <init-param> <param-name>enablePooling</param-name> <param-value>false</param-value> </init-param> 清空%tomcat%\conf\目录
TagSupport类的几个重要方法说明
doStartTag() 在开始标签属性设置后调用,如果返回SKIP_BODY则忽略标签之中的内容,如果返回EVAL_BODY_INCLUDE则将标签体的内容进行输出
doEndTag() 在结束标签之前调用,返回SKIP_PAGE跳过整个jsp页面后面的输出,返回EVAL_PAGE执行页面余下部分
release() 生命周期结束时调用
tld文件定义的相关配置说明
<!--版本号--> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <!-- 引用标签默认的前缀,可在jsp引用时修改 --> <short-name>ytag</short-name> <tag> <!—指定标签名 --> <name>TestSelectTag</name> <!—指定标签类文件的全路径 --> <tag-class>com.taglib.TestTag</tag-class> <!--如果不需要标签体则设置empty,反之设定jsp --> <body-content>empty</body-content> <!—设定属性(如果有的话) --> <attribute> <!—指定标签名 --> <name>name</name> <!—是否是必须,如果非必须没设置则为空 --> <required>false</required> <rtexprvalue>true</rtexprvalue><!—是否可在属性中使用表达式 --> </attribute> </tag>