J
Jun
I placed a print statement in each callback method in iterating BodyTag and
the print statement prints "Enter ...". I got following
doStartTag
doEndTag
doAfterBody
doAfterBody
doAfterBody
doAfterBody
doAfterBody
My question is why doEndTag was called before DoAfter Body?
Here is the jsp
....
<mylib:loop iterations="5"> </mylib:loop>
....
Here is the definition
....
<tag>
<name>loop</name>
<tagclass>coolshare.tag.LoopTag</tagclass>
<bodycontent>JSP</bodycontent>
<info>A BodyTag for looping</info>
<attribute>
<name>iterations</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
....
And here is the BodyTag java src
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* A simple BodyTag that Loops a given number of times
* @author Magnus Rydin
*/
public class LoopTag implements BodyTag
{
private Tag parent;
private BodyContent bodyContent;
private PageContext pageContext;
private int iterations=0;
/**
* Constructor
*/
public LoopTag()
{
super();
}
/**
* Method called by the Container to set the PageContext
*/
public void setPageContext(PageContext pageContext)
{
this.pageContext=pageContext;
}
/** Method used by the JSP container to set the parent of the Tag
* @param parent, the parent Tag
*/
public void setParent(final javax.servlet.jsp.tagext.Tag parent)
{
this.parent=parent;
}
/**
* Method used by the JSP container to set the number of iterations to do
*/
public void setIterations(int iterations)
{
this.iterations=iterations;
}
/**
* Method called at start of tag
* @return either a EVAL_BODY_TAG or a SKIP_BODY
*/
public int doStartTag() throws JspTagException
{
print("doStartTag");
if(iterations>0)
{
return EVAL_BODY_AGAIN;
}
else
{
return SKIP_BODY;
}
}
/**
* Method called by the Container to set the BodyContent
*/
public void setBodyContent(BodyContent bodyContent)
{
this.bodyContent=bodyContent;
}
/**
* Method Called before the first time the body is evaluated
*/
public void doInitBody() throws JspTagException{}
/**
* Method called after each evaluation of the body
* @return either EVAL_BODY_TAG or SKIP_BODY
*/
public int doAfterBody() throws JspTagException
{
print("doAfterBody");
if(iterations>1)
{
//decrease the number of iterations left to do
iterations--;
return EVAL_BODY_AGAIN;
}
else
{
return SKIP_BODY;
}
}
/**
* Method Called at end of tag
* @return either EVAL_PAGE or SKIP_PAGE
*/
public int doEndTag() throws JspTagException
{
print("doEndTag");
try
{
if(bodyContent != null) // Check if we even entered the body
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}
catch(java.io.IOException e)
{
throw new JspTagException("IO Error: " + e.getMessage());
}
return EVAL_PAGE;
}
/**
* Method called to releases all resources
*/
public void release() {}
/** Method for retrieving the parent
* @return the parent
*/
public javax.servlet.jsp.tagext.Tag getParent()
{
return parent;
}
private void print(String s)
{
try
{
pageContext.getOut().println("<br>"+s+"<br>");
}
catch(Exception e)
{
}
}
}
the print statement prints "Enter ...". I got following
doStartTag
doEndTag
doAfterBody
doAfterBody
doAfterBody
doAfterBody
doAfterBody
My question is why doEndTag was called before DoAfter Body?
Here is the jsp
....
<mylib:loop iterations="5"> </mylib:loop>
....
Here is the definition
....
<tag>
<name>loop</name>
<tagclass>coolshare.tag.LoopTag</tagclass>
<bodycontent>JSP</bodycontent>
<info>A BodyTag for looping</info>
<attribute>
<name>iterations</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
....
And here is the BodyTag java src
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* A simple BodyTag that Loops a given number of times
* @author Magnus Rydin
*/
public class LoopTag implements BodyTag
{
private Tag parent;
private BodyContent bodyContent;
private PageContext pageContext;
private int iterations=0;
/**
* Constructor
*/
public LoopTag()
{
super();
}
/**
* Method called by the Container to set the PageContext
*/
public void setPageContext(PageContext pageContext)
{
this.pageContext=pageContext;
}
/** Method used by the JSP container to set the parent of the Tag
* @param parent, the parent Tag
*/
public void setParent(final javax.servlet.jsp.tagext.Tag parent)
{
this.parent=parent;
}
/**
* Method used by the JSP container to set the number of iterations to do
*/
public void setIterations(int iterations)
{
this.iterations=iterations;
}
/**
* Method called at start of tag
* @return either a EVAL_BODY_TAG or a SKIP_BODY
*/
public int doStartTag() throws JspTagException
{
print("doStartTag");
if(iterations>0)
{
return EVAL_BODY_AGAIN;
}
else
{
return SKIP_BODY;
}
}
/**
* Method called by the Container to set the BodyContent
*/
public void setBodyContent(BodyContent bodyContent)
{
this.bodyContent=bodyContent;
}
/**
* Method Called before the first time the body is evaluated
*/
public void doInitBody() throws JspTagException{}
/**
* Method called after each evaluation of the body
* @return either EVAL_BODY_TAG or SKIP_BODY
*/
public int doAfterBody() throws JspTagException
{
print("doAfterBody");
if(iterations>1)
{
//decrease the number of iterations left to do
iterations--;
return EVAL_BODY_AGAIN;
}
else
{
return SKIP_BODY;
}
}
/**
* Method Called at end of tag
* @return either EVAL_PAGE or SKIP_PAGE
*/
public int doEndTag() throws JspTagException
{
print("doEndTag");
try
{
if(bodyContent != null) // Check if we even entered the body
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}
catch(java.io.IOException e)
{
throw new JspTagException("IO Error: " + e.getMessage());
}
return EVAL_PAGE;
}
/**
* Method called to releases all resources
*/
public void release() {}
/** Method for retrieving the parent
* @return the parent
*/
public javax.servlet.jsp.tagext.Tag getParent()
{
return parent;
}
private void print(String s)
{
try
{
pageContext.getOut().println("<br>"+s+"<br>");
}
catch(Exception e)
{
}
}
}