aspose file tools*
The moose likes Web Component Certification (SCWCD/OCPJWCD) and the fly likes EVAL_BODY_BUFFERED question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Web Component Certification (SCWCD/OCPJWCD)
Bookmark "EVAL_BODY_BUFFERED question" Watch "EVAL_BODY_BUFFERED question" New topic
Author

EVAL_BODY_BUFFERED question

Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14687
    
  16



1. When returning EVAL_BODY_INCLUDE in doStartTag(),
"IN doAfterBody()" will be output in both the log file and the browser.


2. When returning EVAL_BODY_BUFFERED in doStartTag(),
"IN doAfterBody()" will be output only in the log file.

3. In doEndTag(), out.println(body.getString()); will actually print "IN doAfterBody()".
So the outstream (pageContext.getOut()) I used in doAfterBody was actually the bodyContent buffer.

I'm getting confused about this buffer thing. Could anybody explain ?

getPreviousOut() seems to have something to do with this.
Or even getEnclosingWriter().
I don't understand how to use them. If anybody could explain.

[ December 22, 2005: Message edited by: Satou kurinosuke ]
[ December 22, 2005: Message edited by: Satou kurinosuke ]

[My Blog]
All roads lead to JavaRanch
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
It would have helped if you had provided the complete handler implementation code, and not just the doAfterBody() method, but I think I've guessed correctly what you mean...

The buffer is a BodyContent instance. When using the buffer (signalled by returning EVAL_BODY_BUFFERED from doStartTag()), the first thing the container does is invoke the pageContext.pushBody() method, which causes the current 'out' Writer (perhaps of the parent buffered BodyTag or of the JSP page itself if there is no parent buffered BodyTag) to be stored on the stack, and a new BodyContent to be returned. The push/pop stack facility is used to provide Writers distinct from the actual response stream which can be used to control the flow of content to the response.

Now, recall that for content of a buffered BodyTag to be written to the response, you need to explicitly write it using methods on BodyContent (such as writeOut(getEnclosingWriter()) which will write the entire contents to the parent's BodyContent or 'out' if there is no parent BodyContent).

1. In your code, if you return EVAL_BODY_INCLUDE from doStartTag(), then by the time you get to doAfterBody(), no BodyContent buffer exists in your handler (because you didn't return EVAL_BODY_BUFFERED). Hence, the 'out' object is the actual page's JspWriter (or the BodyContent of a parent tag which has been invoked). So, calling out.println(...) will write the contents directly to the JspWriter for the page, which is in turn written to the response (and shown in the browser).

2. If you return EVAL_BODY_BUFFERED from doStartTag(), the BodyContent buffer is initialised by calling PageContext.pushBody(). The new 'out' object returned by getOut() is the BodyContent buffer and NOT the original JspWriter for the page. So, now invoking out.println(...) writes to the BodyContent for the tag and not directly to the JspWriter for the page. BUT, since you never write the contents of the BodyContent explicitly to the page, this will never be written to the page or the response stream, so it is lost forever (which is why it appears only in the logs).

3. Now, assuming the buffer was initialised (in the 'body' variable), invoking body.getString() returns the String contents of the BodyContent buffer. You then write that explicitly to an output stream, thus flushing the buffer (containing the data you wrote in doAfterBody()) into another stream. What you haven't specified is where the 'out' variable here points to - is it the System.out or the pageContext.getOut()? I assume it is System.out, since pageContext.getOut() actually still refers to the BodyContent buffer - writing the buffer into itself isn't the best thing to do (and won't give you any output).

BodyContent.getEnclosingWriter() returns the parent JspWriter - either the parent buffered BodyTag's BodyContent, or the page's JspWriter. BodyTagSupport.getPreviousOut() is synonymous to invoking BodyContent.getEnclosingWriter().


NOTE: I've avoided a discussion of SimpleTags here. A SimpleTag has its own JspFragment buffering mechanism which is distinct from the classic model, and is not actually (and neither does contain) a JspWriter.
[ December 22, 2005: Message edited by: Charles Lyons ]

Charles Lyons (SCJP 1.4, April 2003; SCJP 5, Dec 2006; SCWCD 1.4b, April 2004)
Author of OCEJWCD Study Companion for Oracle Exam 1Z0-899 (ISBN 0955160340 / Amazon Amazon UK )
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14687
    
  16

I did not understand about the 'out' stream being pushed.
Now it's all clear.

Thank you very much for the very detailed explanations.

I wished the explanations in Manning's book were clear like yours
[ December 22, 2005: Message edited by: Satou kurinosuke ]
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
Originally posted by Satou kurinosuke:
I wished the explanations in Manning's book were clear like yours


Well, I hope my SCWCD book (see my signature) will be available for purchase in January next year, so if you're studying for the SCWCD, I'd be grateful if you'd take a look!
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14687
    
  16

I passed the exam on Saturday !
Wish you good luck for your book.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: EVAL_BODY_BUFFERED question
 
Similar Threads
EVAL_BODY_BUFFERED behavior
Can doAfterBody() return EVAL_BODY_BUFFERED ?
Custom Tag Qn
BodyTagSupport return values
tagdependent value for the body-content element