The doStartTag() and doEndTag() methods return an int. That int tells the Container what to do next. With doStartTag(), the question the Container asks is, “Should I evaluate the body?” (assuming there is one, and assuming the TLD doesn’t declare the body as empty).
With doEndTag(), the Container asks, “Should I keep evaluating the rest of the calling page?” The return values are represented by constants declared in the Tag and IterationTag interfaces.
Possible return values when you extend TagSupport
The constants used as return values for doStartTag() and doEndTag() return value constants are inconsistently named!
With doStartTag(), the return values are SKIP_BODY and EVAL_BODY_INCLUDE. But with doEndTag(), the values are SKIP_PAGE and EVAL_PAGE.
If the names were consistent, doEndTag() would return EVAL_PAGE_INCLUDE (as opposed to EVAL_PAGE), to match the way doStartTag() returns EVAL_BODY_INCLUDE. But it’s not! So don’t be fooled if you see code on the exam with correct-looking (but wrong) return values.
Returning SKIP_PAGE from doEndTag() is exactly like throwing a SkipPageException from a Simple tag! If a page included the page that invoked the tag, the current (included) page stops processing, but the including page continues... ...