When you write a tag handler that extends TagSupport, you get all the lifecycle methods from the Tag interface, plus the one method from IterationTag—doAfterBody(). Without doAfterBody(), you can’t iterate over the body because doStartTag() is too early, and doEndTag() is too late. But with doAfterBody(), your return value tells the Container whether it should repeat the body again (EVAL_BODY_AGAIN) or call the doEndTag() method (SKIP_BODY).
Sharpen your pencil
Try to implement the same functionality of this SimpleTag doTag() in a Classic tag handler. Assume the TLD is configured to allow body content.
BE the Container
Look at the legal tag handler code below and figure out whether it would give you the result shown, given the JSP tag invocation listed below. This is also the same result produced by the ClassicTag handler from the previous page. Yes, we’re answering the Sharpen Your Pencil with yet another exercise...
The tag handler class
// package and imports public class MyIteratorTag extends TagSupport { String[] movies= new String[] {"Spiderman", "Saved!", "Amelie"}; int movieCounter; public int doStartTag() throws JspException { movieCounter=0; return EVAL_BODY_INCLUDE; } public int doAfterBody() throws JspException { if (movieCounter < movies.length) { pageContext.setAttribute("movie", movies[movieCounter]); movieCounter++; return EVAL_BODY_AGAIN; } else { return SKIP_BODY; } } public int doEndTag() throws JspException { return EVAL_PAGE; } }
JSP that invokes the tag
<%@ taglib prefix="mine" uri="KathyClassicTags" %> <html><body> <table border="1"> <mine:iterateMovies> <tr><td>${movie}</td></tr> </mine:iterateMovies> </table> </body></html>
Desired result