掌握基本的标签定义后,可以发现定义标签时都需要继承TagSupport这个类,TagSupport类是整个标签编程的一个核心类,此类定义如下:
public class TagSupport extends Objet implements IterationTag,Serizlizable
它同时实现了IteratorTag和Serializable两个接口,IterationTag接口的定义如下:
public interface IterationTag extends Tag{ public static final int EVAL_BODY_AGAIN; public int doAfterBody() throws JspException; }
IterationTag本身又是Tag接口的子接口,Tag接口定义如下:
public interface Tag extends JspTag{ public static final int SKIP_BODY; public static final int EVAL_BODY_INCLUDE; public static final int SKIP_PAGE; public static final int EVAL_PAGE; public void setPageContext(PageContext pc); public void setParent(Tag t); public Tag getParent(); public int doStartTag() throws JspException; public int doEndTag() throws JspException; public void release(); }
TagSupport类中定义的常量及方法:
No | 常量及方法 | 类型 | 描述 |
1 | protected PageContext pageContext | 属性 | 表示pageContext对象,可以操作4种属性范围 |
2 | public static final int SKIP_BODY | 常量 | 忽略标签体内容,将操作转交给doEndTag() |
3 | public static final int EVAL_BODY_INCLUDE | 常量 | 正常执行标签体操作,但不处理任何运算 |
4 | public static final int SKIP_PAGE | 常量 | 所在在JSP上的操作走将停止,会将所有输出的内容立刻显示在浏览器上 |
5 | public static final int EVAL_PAGE | 常量 | 正常执行JSP页面 |
6 | public static final int EVAL_BODY_AGAIN | 常量 | 重复执行标签体内容,会再次调用doAfterBody(),直到出现SKIP_BODY为止 |
7 | public int doStartTag() throws JspException | 方法 | 处理标签开始部分 |
8 | public int doEndTag() throws JspException | 方法 | 处理标签结束部分 |
9 | public int doAfterBody() throws JspException | 方法 | 处理标签主体部分 |
10 | public viod release() | 方法 | 释放标签资源 |
doStartTag():此方法忽略标签开始时执行,返回值如下:
doAfterBody():此方法是IterationTag接口于Tag接口的区别所在,用来重复执行标签体的内容,返回治如下:
doEndTag():此方法在标签结束时执行,返回值如下:
release():将标签处理类所产生或是获得的资源全部释放,并等待用户下次继续使用;
实现一个有标签体的标签库:
演示一个包含方法体标签的开发,主要完成:判断在某一属性中是否存在指定的属性,如果存在,则进行输出。
AttributeTag:
package com.keith.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; public class AttributeTag extends TagSupport { //接受属性名称 private String name; //接受查找范围 private String scope; @Override public int doStartTag() throws JspException { Object value = null; //是否是page范围 if ("page".equals(this.scope)) { value = super.pageContext .getAttribute(name, PageContext.PAGE_SCOPE); } else if ("request".equals(this.scope)) { //是否是request范围 value = super.pageContext.getAttribute(name, PageContext.REQUEST_SCOPE); } else if ("session".equals(this.scope)) { //是否是session范围 value = super.pageContext.getAttribute(name, PageContext.SESSION_SCOPE); } else { //是否是application范围 value = super.pageContext.getAttribute(name, PageContext.APPLICATION_SCOPE); } //如果没有查到属性 if (value ==null) { //不执行标签体内容 return TagSupport.SKIP_BODY; }else{ //找到属性,执行标签题内容 return TagSupport.EVAL_BODY_INCLUDE; } } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } }
attributetag.tld:
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 标签库的版本 --> <tlib-version>1.0</tlib-version> <!-- 为标签苦在TLD中的描述名称 --> <short-name>attributetag</short-name> <tag> <!-- 表示标签在JSP中的使用名称 --> <name>present</name> <!-- 表示这个标签所这项的Class --> <tag-class>com.keith.tag.AttributeTag</tag-class> <!-- 标签体内容为空 --> <body-content>JSP</body-content> <attribute> <!-- format为属性名 --> <name>name</name> <!-- 表示此值必须设置 --> <required>true</required> <!-- 表示属性值是请求时表达式的结果 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <!-- format为属性名 --> <name>scope</name> <!-- 表示此值必须设置 --> <required>true</required> <!-- 表示属性值是请求时表达式的结果 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
web.xml:
<taglib> <taglib-uri>attribute</taglib-uri> <taglib-location>/WEB-INF/attributetag.tld</taglib-location> </taglib>
index.jsp:
<%@ taglib prefix="attributetag" uri="attribute"%> <body> <hr /> <% String scope = "session"; session.setAttribute("name","keith"); %> <attributetag:present name="name" scope="<%=scope %>"> <%=scope %>范围内存在:"${sessionScope.name }" </attributetag:present> </body>