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.