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.8


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.

Reply via email to