There are classes provided in the javax.servlet.jsp.tagext package which provide default implementation for the above interfaces :
The six methods which Tag interface provides and which we have to implement are :
- setPageContext(PageContext pc)
- setParent(Tag parent)
If there are attributes in tag then we have additional setter & getter for them.
Tag Interface Lifecycle
- The setPageContext() method : is the first method that is called in the life cycle of a custom tag.
- The setParent() and getParent() methods : are used when custom tags are nested one inside the other. The JSP container calls the setParent() method on the child tag and passes it a reference to the parent tag. The getParent() method is usually called by one of the child tags and not directly by the JSP container.
- the setters of attributes are called
- doStartTag() method : After setting up the tag with appropriate references by calling the setPageContext(), setParent(), and setter methods, the container calls the doStartTag() method on the tag. After initialization, the doStartTag() method decides whether or not to continue evaluating its body content. As a result, it returns one of the two integer constants defined in the Tag interface: EVAL_BODY_INCLUDE or SKIP_BODY. May throw a JSPException.
- doEndTag() method : After the body of the tag is evaluated or skipped (depending on the return value of doStartTag()), the container calls the doEndTag() method. May throw a JSPException.
- release() method : Finally, the container calls the release() method on the handler class when the tag handler object is no longer required. A custom tag may occur multiple times on a JSP page. A single instance of the tag handler may be used to handle all of these occurrences. The JSP container calls the release() method on the handler class when the handler object is no longer required. It is important to note that this method is not called after every call to doEndTag().
The IterationTag interface extends the Tag interface and allows us to include the body content multiple times, in a way that is similar to the loop functionality of a programming language. The IterationTag interface declares one method and one constant
int doAfterBody() : This method is called after each evaluation of the tag body. It can return either of two values: IterationTag.EVAL_BODY_AGAIN or Tag.SKIP_BODY. The return value determines whether or not the body needs to be reevaluated.
EVAL_BODY_AGAIN : Return value for doAfterBody(). This constant instructs the JSP engine to evaluate the tag body and include it in the output.
If doStartTag() returns SKIP_BODY, then the body is skipped and the container calls doEndTag(). In this case, the doAfterBody() method is never called on the iterative tag. However, if doStartTag() returns EVAL_BODY_INCLUDE, the body of the tag is evaluated, the result is included in the output, and the container calls doAfterBody() for the very first time.
The BodyTag interface extends IterationTag and adds a new functionality that lets the tag handler evaluate its body content in a temporary buffer. This feature allows the tag to process the generated contents at will. For example, after evaluation, the tag handler can view the body content, discard it completely, modify it, or add more data to it before sending it to the output stream. Since it is derived from IterationTag, BodyTag can also handle the evaluation and processing of the content as many times as required.
void setBodyContent(BodyContent) : Called by the JSP container to pass a reference to a
void doInitBody( ) : Called by the JSP container after calling setBodyContent(), to allow the tag handler class to perform initialization steps on BodyContent.
EVAL_BODY_BUFFERED : A constant defined as a return value for doStartTag() and doAfterBody() for tags that want to buffer the evaluation of their content
The doStartTag() method of a class that implements the BodyTag interface returns any one of three values: EVAL_BODY_INCLUDE or SKIP_BODY inherited from the Tag interface, or EVAL_BODY_BUFFERED, which is defined in the BodyTag interface. The actions taken by the JSP container for the return values EVAL_BODY_INCLUDE and SKIP_BODY are the same as for the IterationTag interface.
However, if doStartTag() returns EVAL_BODY_BUFFERED, the JSP container takes a different course of action. It first creates an instance of the BodyContent class. The BodyContent class is a subclass of JspWriter and overrides all the print and write methods of JspWriter to buffer any data written into it rather than sending it to the output stream of the response. The JSP container passes the newly created BodyContent instance to the tag handler using its setBodyContent() method, calls doInitBody() on the tag, and finally evaluates the body of the tag, filling the BodyContent buffer with the result of the body tag evaluation.
The container calls doAfterBody() after evaluating the body, writing the data directly into the output or buffering it, as the case may be. If the output was buffered, we can add, modify, or delete the contents of this buffer. Finally, this method returns EVAL_BODY_AGAIN or EVAL_BODY_BUFFERED to continue evaluating the body in a loop, or returns SKIP_BODY to terminate the loop.
Finally, the container calls doEndTag(), and, as with the other interfaces, the tag handler class that is implementing the BodyTag interface can return either SKIP_PAGE or EVAL_PAGE.