最近在建立自定义标签并使用时,对于返回的值EVAL_BODY_INCLUDE、SKIP_BODY、EVAL_BODY_AGAIN、EVAL_PAGE、SKIP_PAGE分不太清楚,看网上的相关博客虽然讲得较为清晰,但是为了更加彻底地清楚他们的区别,动手写了一个实例,终于弄明白它们的区别,也是伤不起咯!
首先,建一个自定义标签的.tld文件,
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>role</shortname> <uri>http://www.hhhh.com</uri> <info>Test Tags Library</info> <tag> <name>display</name> <tagclass>com.xxx.tag.TestTag</tagclass> <bodycontent>jsp</bodycontent> <info>just a test</info> <attribute> <name>type</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
这个tld文件里面定义了一个名为display的tag,这个tag包含了一个名为type的属性。
在测试页面引用这个自定义标签。
<%@ taglib uri="/WEB-INF/tld/kkfun-test.tld" prefix="test"%> <test:display type="lala">热血高校</test:display>超级
所以,接下来开始定义相应的标签处理类:
public class TestTag extends BodyTagSupport { private String type; @Override public int doAfterBody() throws JspException { System.out.println("=========doAfterBody========="); return SKIP_BODY;//EVAL_BODY_AGAIN; } @Override public int doEndTag() throws JspException { System.out.println("========doEndTag========="); JspWriter out = this.pageContext.getOut(); try { out.println("Hello !!!!"); } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE;//SKIP_PAGE; } @Override public int doStartTag() throws JspException { System.out.println("======doStartTag========"); System.out.println("then you must call " + type.toUpperCase() + " first"); return SKIP_BODY;//EVAL_BODY_INCLUDE; } public String getType() { return type; } public void setType(String type) { this.type = type; }
需要注意的是,BodyTagSupport extends TagSupport,而我们一般来说用得较多的还是BodyTagSupport 。
整理如下:
1)标签处理类中extends BodyTagSupport ,一般来讲实现的三个方法是doStartTag,doAfterBody,doEndTag。
2)根据打印结果顺序:
======doStartTag======== then you must call LALA first ========doAfterBody========= ========doEndTag=========
可以看出标签处理类执行方法的一般顺序为:doStartTag()->doAfterBody()->doEndTag()
3)doStartTag()方法的合理返回值为EVAL_BODY_INCLUDE和SKIP_BODY
----------返回值为EVAL_BODY_INCLUDE时,表明执行标签体中间的内容,页面上的结果为:热血高校Hello !!!! 超级
----------返回值为SKIP_BODY时,表明不执行标签体中间的内容,页面上的结果为:Hello !!!! 超级
4)doAfterBody()方法的合理返回值为SKIP_BODY和EVAL_BODY_AGAIN
---------返回值为SKIP_BODY时,表示继续处理标签执行的下一步,页面上的结果为:热血高校Hello !!!! 超级
---------返回值为为EVAL_BODY_AGAIN时,表示会重复执行标签体中间的内容,页面上的结果为:热血高校热血高校热血高校Hello !!!! 超级
5)doEndTag()的合理返回值为EVAL_PAGE和SKIP_PAGE
---------返回值为EVAL_PAGE时,表示标签结束后继续执行页面上的内容,页面上的结果为:热血高校Hello !!!! 超级
---------返回值为为SKIP_PAGE时,表示不继续执行结束标签后的内容,页面上的结果为:热血高校Hello !!!!
巧妙的实际应用:比如一个管理系统的权限问题,当登录用户的用户类型符合某一集合时,就显示在自定义标签中的内容,此时doStartTag()返回EVAL_BODY_INCLUDE,表明他有权限访问标签体当中的内容;反之,当他不在这个集合中时,doStartTag()返回SKIP_BODY,表明不显示标签体中的内容,也就是没有权限访问。
小结:一般而言,doStartTag()返回SKIP_BODY,doAfterBodyTag()返回SKIP_BODY,doEndTag()返回EVAL_PAGE.
相关推荐
1. `doStartTag()`:初始化标签,可以返回`SKIP_BODY`、`EVAL_BODY_INCLUDE`或`EVAL_BODY_AGAIN/EVAL_BODY_BUFFERED`。 2. `doInitBody()`(仅在实现了`BodyTag`或`BodyTagSupport`时使用):进行标签体的一些初始化...
- `doStartTag()`: 返回值可为`BodyTag.SKIP_BODY`(跳过Body并直接调用`doEndTag()`)、`BodyTag.EVAL_BODY_INCLUDE`(包括Body并继续)或`BodyTag.EVAL_BODY_BUFFERED`(缓冲Body内容)。 - `doAfterBody()`: ...
返回值同样有`EVAL_BODY_AGAIN`、`SKIP_BODY`和`SKIP_PAGE`供选择。 3. `doEndTag()`:在标签结束时调用,处理页面剩余部分。返回值`EVAL_PAGE`表示继续处理余下页面。 二、返回值作用域 理解这些返回值的作用至关...
例如,返回`Tag.EVAL_BODY_AGAIN`表示需要继续读取下一个字符,而`Tag.SKIP_BODY`则停止处理。 5. **doEndTag()**:这是标签生命周期的最后一个方法,当遇到标签结束标记时调用。在此处进行清理工作,如释放资源或...
1. **Tag**: 这是所有传统标签的父接口,它定义了两个核心方法 `doStartTag()` 和 `doEndTag()`,以及四个常量 `EVAL_BODY_INCLUDE`、`SKIP_BODY`、`EVAL_PAGE` 和 `SKIP_PAGE`。 - `doStartTag()`: 当JSP引擎遇到...
- `EVAL_BODY_INCLUDE`: 处理标签体,但忽略`setBodyContent()`和`doInitBody()`。 - `EVAL_BODY_AGAIN`: 对标签体进行循环处理。 2. **标签库描述文件(.tld)** - .tld文件是XML格式,用于定义标签库,包括...
- `EVAL_BODY_INCLUDE`:表示需要执行后续的标签体,并允许在标签体中访问当前迭代的元素。 - `SKIP_BODY`:如果集合为空或未找到,则跳过标签体。 #### 2. `doAfterBody()` 方法 - **作用**:在每次迭代后被调用...
4. `doAfterBody`方法:给定的JavaBean代码中,`doAfterBody`方法会连续输出两次"good",因为每次返回`EVAL_BODY_AGAIN`时会再次调用此方法,直到num达到2,然后返回`SKIP_BODY`结束。所以选项B正确,输出两次。 5....
- `EVAL_BODY_INCLUDE`或`EVAL_BODY_AGAIN`:处理标签体并可能重复处理。 - `SKIP_PAGE`:停止当前页面的进一步处理,直接将结果返回给客户端。 - `EVAL_PAGE`:继续执行剩余的页面内容。 **标签库描述文件(....
而doEndTag()方法返回Tag.EVAL_PAGE表示标签后的页面内容将继续被处理,返回Tag.SKIP_PAGE则表示不处理后续的页面内容。 对于带内容体的标签处理器类,除了doStartTag()和doEndTag()方法,还需要覆盖doAfterBody()...