You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Musachy Barroso (JIRA)" <ji...@apache.org> on 2009/08/13 00:16:59 UTC

[jira] Commented: (WW-3195) When FreemarkerResult isn't writing directly to Response, s.action tag is broken

    [ https://issues.apache.org/struts/browse/WW-3195?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46618#action_46618 ] 

Musachy Barroso commented on WW-3195:
-------------------------------------

I am very uncomfortable making this change and risking breaking normal results just to fix the "action" tag when using freemarker, I will move this

> When FreemarkerResult isn't writing directly to Response, s.action tag is broken
> --------------------------------------------------------------------------------
>
>                 Key: WW-3195
>                 URL: https://issues.apache.org/struts/browse/WW-3195
>             Project: Struts 2
>          Issue Type: Bug
>    Affects Versions: 2.1.7
>            Reporter: Jasper Rosenberg
>             Fix For: 2.1.9
>
>
> In https://issues.apache.org/struts/browse/WW-1808, the FreemarkerResult was improved to support not writing to the response until it had completed processing.
> Unfortunately, if you are using an s.action tag, then that means the s.action output ends up before the main template output rather than inline.
> One way to fix this (which I did locally) is to add a thread local that keeps track of the "parent" writer such that if there is one present the child writes to that at the end rather than the response's writer.
> Something like:
>     /** Thread local for the current writer. */
>     private static final ThreadLocal<CharArrayWriter> WRITER_THREAD_LOCAL 
>         = new ThreadLocal<CharArrayWriter>();
> ...
>    // Inside the case where we are writing upon completion
>             CharArrayWriter parentCharArrayWriter = WRITER_THREAD_LOCAL.get();
>             try {
>                 // Process the template with the normal writer since it was available
>                 // But delay writing in case exception
>                 CharArrayWriter charArrayWriter = new CharArrayWriter(1024);
>                 
>                 if (parentCharArrayWriter == null) {
>                     WRITER_THREAD_LOCAL.set(charArrayWriter);
>                 }
>                 
>                 template.process(model, charArrayWriter);
>                 charArrayWriter.flush();
>                 // Only the template that created the writer can actually write
>                 // to the response.  This is necessary to support the s.action tag.
>                 if (parentCharArrayWriter == null) {
>                     charArrayWriter.writeTo(writer);  // Write to the response writer
>                 } else {
>                     // Copying to parent enmass so don't get partially rendered s.actions
>                     charArrayWriter.writeTo(parentCharArrayWriter);
>                 }
>             } finally {
>                 if (parentCharArrayWriter == null) {
>                     WRITER_THREAD_LOCAL.remove();
>                 }
>             }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.