Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

ClassicTag issue

 
Steven Colley
Ranch Hand
Posts: 290
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Folks, help me here:


What is the result of accessing the following JSP document? (Choose one.)
JSP document:
<html xmlns:mytags="http://www.osborne.com/taglibs/mytags"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jsp/jstl/core" >
<jsp utput omit-xml-declaration="true" />
<jsp irective.page contentType="text/html" />
<jsp irective.page import="java.io.Writer" />
<body>

<jsp:scriptlet>Writer myOut = pageContext.getOut();</jsp:scriptlet>
<mytags:question18>
<jsp:scriptlet>myOut.write("Body");</jsp:scriptlet>
</mytags:question18>

</body>
</html>


import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;

public class Question18 extends BodyTagSupport {

public int doAfterBody() throws JspException {
try {
bodyContent.write("Legs");
bodyContent.writeOut(bodyContent.getEnclosingWriter());
} catch (IOException e) {
throw new JspException(e);
}
return Tag.EVAL_PAGE;
}

public void doInitBody() throws JspException {
try {
bodyContent.write("Head");
} catch (IOException e) {
throw new JspException(e);
}
}
}

A.Translation error (source generation)
B.Translation error (source compilation)
C.Run-time error
D.Output of HeadBodyLegs
E.Output of BodyHeadLegs
F. Output of BodyHeadBodyLegs


According to the mock�s engine the answer is : "E".


My question is..how is it possible..if we dind't declare a overrided doStartTag method in "Question18" class.

For me, "doAfterBody" is not supposed to be processed, since it�s a Classic tag, and the default value for doStartTag is "SKIP_BODY".

Therefore, neither the "body" would be processed nor "doAfterBody" and "doInitBody" would be executed too.

What dind't i figure out here? ???

Ah, and another thing...(doAfterBody shouldn�t be returning "EVAL_PAGE" since it�s "doEndTag�s method".
Would it be a runtime exception right?

Tks.
 
Aleksander Zielinski
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Where did you find this question?
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For me, "doAfterBody" is not supposed to be processed, since it's a Classic tag, and the default value for doStartTag is "SKIP_BODY".

You are incorrect - not overriding doStartTag() in TagSupport would skip the body; but in BodyTagSupport, this method returns EVAL_BODY_BUFFERED, so in fact nothing goes wrong there, and the question is correct from that perspective.

The question is also correct because the tag uses a buffer; doInitBody() is invoked first and starts writing "Head" to the buffer. Then the body content of the tag is invoked, causing the scriptlet to write "Body" directly to 'out', then the doAfterBody() writes "Legs" to the buffer. The final buffer content is "HeadLegs", so when it is appended to 'out' in doAfterBody(), the final output becomes "BodyHeadLegs".

Ah, and another thing...(doAfterBody shouldn�t be returning "EVAL_PAGE" since it�s "doEndTag�s method".
Would it be a runtime exception right?

You are correct, it should return EVAL_BODY_AGAIN to evaluate the body once more, or SKIP_BODY to jump to doEndTag(). However, it may not cause a runtime exception, because these constants are numerical, so if the numerical value of EVAL_PAGE matches with the numerical value of a valid constant, everything will still work (perhaps not correctly). EVAL_PAGE actually has the value 6, while no other valid value for doAfterBody() does, so in fact you would get some sort of problem here... However, the value of constants should never be relied upon (and I wouldn't be surprised to see this replaced with a type-safe enum in a much later release).

I also have a reservation here because doAfterBody() never seems to return SKIP_BODY. What would actually happen in practise is the body would be evaluated infinitely, and probably end up with a container stack overload, and a restart of the Web server! At some point you must return SKIP_BODY from doAfterBody() to end the tag's invocation. From this perspective, I think the actual answer would be "BodyHeadLegsBodyLegsBodyLegs..." ad infinitum.
[ April 16, 2006: Message edited by: Charles Lyons ]
 
Steven Colley
Ranch Hand
Posts: 290
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Great Charles Tks.

U�re right, The doStartTag really returns "EVA_BODY_BUFFERED" intead of "SKIP_BODY" for BodyTagSupport classes, i din�t pay attention it...

But another question regarding the answer.

Why does "body" appear before "Head"? because it�s a scripting?

Because "doInitBody" is supposed to be executed before processing the body, ins�t it?


Tks.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic