IterationTag是javax.servlet.jsp.tagext包下的接口,其扩展自Tag接口。IterationTag接口中定义了一个doAfterBody()方法,此方法的作用是可以重复执行BODY中的内容,所谓BODY是指标签中间的内容,比如<a>BODY</a>,先上一张图来看一下此接口的执行流程:
下面上具体的例子:
首先创建一个标签类实现IterationTag接口:
1 public class TestIterationTag implements IterationTag { 2 private PageContext pageContext; 3 private List<String> list; 4 private String item; 5 private Iterator<String> it; 6 //省略GET SET方法 7 8 public int doEndTag() throws JspException { 9 System.out.println("doEndTag..."); 10 return 0; 11 } 12 13 public int doStartTag() throws JspException { 14 System.out.println("doStartTag..."); 15 it = list.iterator(); 16 if (it.hasNext()) { 17 pageContext.setAttribute(item, it.next()); 18 } 19 return EVAL_BODY_INCLUDE; 20 } 21 22 public Tag getParent() { 23 return null; 24 } 25 26 public void release() { 27 } 28 29 public void setPageContext(PageContext paramPageContext) { 30 this.pageContext = paramPageContext; 31 } 32 33 public void setParent(Tag paramTag) { 34 } 35 36 public int doAfterBody() throws JspException { 37 if (it.hasNext()) { 38 pageContext.setAttribute(item, it.next()); 39 return (EVAL_BODY_AGAIN); 40 } else { 41 return SKIP_BODY; 42 } 43 } 44 }
然后是JSP文件:
1 <body> 2 <% 3 List<String> list = new ArrayList<String>(); 4 list.add("test01"); 5 list.add("test02"); 6 list.add("test03"); 7 list.add("test04"); 8 list.add("test05"); 9 application.setAttribute("list", list); 10 %> 11 <web:testIteration list = "${list }" item="item"> 12 <%=pageContext.getAttribute("item") %> 13 </web:testIteration> 14 </body>
这个JSP文件中的标签的BODY就是<%=pageContext.getAttribute("item") %>,那么当doStartTag()执行完毕之后,返回的是EVAL_BODY_INCLUDE,所以会先去执行BODY的代码,然后再去执行标签内中的doAfterBody()方法,然后如果doAfterBody()方法返回的是EVAL_BODY_AGAIN,那么继续先执行BODY,再执行doAfterBody(),如果返回的是SKIP_BODY,则跳出循环,去执行doEndTag()。
再上一个JSP被编译后的Java代码片段:
1 int _jspx_eval_web_005ftestIteration_005f0 = _jspx_th_web_005ftestIteration_005f0.doStartTag(); 2 if (_jspx_eval_web_005ftestIteration_005f0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) { 3 do {// 开始循环执行BODY和doAfterBody()方法 4 out.write(" "); 5 out.write(" "); 6 out.print(pageContext.getAttribute("item") );//执行BODY 7 out.write(' '); 8 out.write(' '); 9 out.write(' '); 10 int evalDoAfterBody = _jspx_th_web_005ftestIteration_005f0.doAfterBody(); 11 if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)//返回EVAL_BODY_AGAIN,继续循环,否则退出循环 12 break; 13 } while (true); 14 }
以上。