mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
WW-3195 When FreemarkerResult isn't writing directly to Response, s.action tag is broken
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@830250 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -117,6 +117,7 @@ public class FreemarkerResult extends StrutsResultSupport {
|
||||
*/
|
||||
protected String location;
|
||||
private String pContentType = "text/html";
|
||||
private static final String PARENT_TEMPLATE_WRITER = FreemarkerResult.class.getName() + ".parentWriter";
|
||||
|
||||
public FreemarkerResult() {
|
||||
super();
|
||||
@@ -158,9 +159,10 @@ public class FreemarkerResult extends StrutsResultSupport {
|
||||
this.configuration = getConfiguration();
|
||||
this.wrapper = getObjectWrapper();
|
||||
|
||||
ActionContext ctx = invocation.getInvocationContext();
|
||||
HttpServletRequest req = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
|
||||
|
||||
if (!locationArg.startsWith("/")) {
|
||||
ActionContext ctx = invocation.getInvocationContext();
|
||||
HttpServletRequest req = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
|
||||
String base = ResourceUtil.getResourceBase(req);
|
||||
locationArg = base + "/" + locationArg;
|
||||
}
|
||||
@@ -174,14 +176,27 @@ public class FreemarkerResult extends StrutsResultSupport {
|
||||
// Process the template
|
||||
Writer writer = getWriter();
|
||||
if (isWriteIfCompleted() || configuration.getTemplateExceptionHandler() == TemplateExceptionHandler.RETHROW_HANDLER) {
|
||||
CharArrayWriter charArrayWriter = new CharArrayWriter();
|
||||
CharArrayWriter parentCharArrayWriter = (CharArrayWriter) req.getAttribute(PARENT_TEMPLATE_WRITER);
|
||||
boolean isTopTemplate = false;
|
||||
if (isTopTemplate = (parentCharArrayWriter == null)) {
|
||||
//this is the top template
|
||||
parentCharArrayWriter = new CharArrayWriter();
|
||||
//set it in the request because when the "action" tag is used a new VS and ActionContext is created
|
||||
req.setAttribute(PARENT_TEMPLATE_WRITER, parentCharArrayWriter);
|
||||
}
|
||||
|
||||
try {
|
||||
template.process(model, charArrayWriter);
|
||||
charArrayWriter.flush();
|
||||
charArrayWriter.writeTo(writer);
|
||||
template.process(model, parentCharArrayWriter);
|
||||
|
||||
if (isTopTemplate) {
|
||||
parentCharArrayWriter.flush();
|
||||
parentCharArrayWriter.writeTo(writer);
|
||||
}
|
||||
} finally {
|
||||
if (charArrayWriter != null)
|
||||
charArrayWriter.close();
|
||||
if (isTopTemplate && parentCharArrayWriter != null) {
|
||||
req.removeAttribute(PARENT_TEMPLATE_WRITER);
|
||||
parentCharArrayWriter.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
template.process(model, writer);
|
||||
|
||||
@@ -30,15 +30,26 @@ import junit.framework.TestCase;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.StrutsTestCase;
|
||||
import org.apache.struts2.dispatcher.Dispatcher;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse;
|
||||
import org.apache.struts2.views.jsp.StrutsMockServletContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import freemarker.template.TemplateExceptionHandler;
|
||||
import freemarker.template.Configuration;
|
||||
|
||||
/**
|
||||
* Test case for FreeMarkerResult.
|
||||
*
|
||||
@@ -55,6 +66,58 @@ public class FreeMarkerResultTest extends StrutsTestCase {
|
||||
private FreemarkerManager mgr;
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
public void testActionThatThrowsExceptionTag() throws Exception {
|
||||
//get fm config to use it in mock servlet context
|
||||
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
|
||||
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
|
||||
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
|
||||
|
||||
ServletContext servletContext = EasyMock.createNiceMock(ServletContext.class);
|
||||
File file = new File(FreeMarkerResultTest.class.getResource("callActionFreeMarker2.ftl").toURI());
|
||||
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl")).andReturn(file.getAbsolutePath());
|
||||
file = new File(FreeMarkerResultTest.class.getResource("nested.ftl").toURI());
|
||||
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/nested.ftl")).andReturn(file.getAbsolutePath());
|
||||
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
|
||||
EasyMock.replay(servletContext);
|
||||
|
||||
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
|
||||
ServletActionContext.setServletContext(servletContext);
|
||||
|
||||
|
||||
request.setRequestURI("/tutorial/test2.action");
|
||||
Dispatcher dispatcher = Dispatcher.getInstance();
|
||||
ActionMapping mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(
|
||||
request, dispatcher.getConfigurationManager());
|
||||
dispatcher.serviceAction(request, response, servletContext, mapping);
|
||||
assertEquals("beforenestedafter", stringWriter.toString());
|
||||
}
|
||||
|
||||
public void testActionThatSucceedsTag() throws Exception {
|
||||
//get fm config to use it in mock servlet context
|
||||
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
|
||||
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
|
||||
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
|
||||
|
||||
ServletContext servletContext = EasyMock.createNiceMock(ServletContext.class);
|
||||
File file = new File(FreeMarkerResultTest.class.getResource("callActionFreeMarker2.ftl").toURI());
|
||||
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/callActionFreeMarker2.ftl")).andReturn(file.getAbsolutePath());
|
||||
file = new File(FreeMarkerResultTest.class.getResource("nested.ftl").toURI());
|
||||
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/nested.ftl")).andReturn(file.getAbsolutePath());
|
||||
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
|
||||
EasyMock.replay(servletContext);
|
||||
|
||||
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
|
||||
ServletActionContext.setServletContext(servletContext);
|
||||
|
||||
|
||||
request.setRequestURI("/tutorial/test5.action");
|
||||
Dispatcher dispatcher = Dispatcher.getInstance();
|
||||
ActionMapping mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(
|
||||
request, dispatcher.getConfigurationManager());
|
||||
dispatcher.serviceAction(request, response, servletContext, mapping);
|
||||
assertEquals("beforenestedafter", stringWriter.toString());
|
||||
}
|
||||
|
||||
public void testWriteIfCompleted() throws Exception {
|
||||
FreemarkerResult result = new FreemarkerResult();
|
||||
result.setLocation("someFreeMarkerFile.ftl");
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<#--
|
||||
/*
|
||||
* $Id: someFreeMarkerFile.ftl 590812 2007-10-31 20:32:54Z apetrelli $
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
before<@s.action namespace="/tutorial" name="test4" executeResult="true" rethrowException="true"/>after
|
||||
@@ -0,0 +1,23 @@
|
||||
<#--
|
||||
/*
|
||||
* $Id: someFreeMarkerFile.ftl 590812 2007-10-31 20:32:54Z apetrelli $
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
before<@s.action namespace="/tutorial" name="test3" executeResult="true" rethrowException="true"/>after
|
||||
@@ -0,0 +1,23 @@
|
||||
<#--
|
||||
/*
|
||||
* $Id: someFreeMarkerFile.ftl 590812 2007-10-31 20:32:54Z apetrelli $
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
nested
|
||||
@@ -40,6 +40,29 @@
|
||||
<action name="test" class="com.opensymphony.xwork2.ActionSupport">
|
||||
<result name="input">sitegraph/guess-input.ftl</result>
|
||||
</action>
|
||||
|
||||
<action name="test2" class="com.opensymphony.xwork2.ActionSupport">
|
||||
<result type="freemarker">
|
||||
<param name="location">org/apache/struts2/views/freemarker/callActionFreeMarker.ftl</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
<action name="test3" class="com.opensymphony.xwork2.ActionSupport">
|
||||
<result type="freemarker">org/apache/struts2/views/freemarker/nested.ftl</result>
|
||||
</action>
|
||||
|
||||
<action name="test4" class="org.apache.struts2.TestAction" method="executeThrowsException">
|
||||
<result type="freemarker">
|
||||
<param name="location">org/apache/struts2/views/freemarker/nested.ftl</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
<action name="test5" class="com.opensymphony.xwork2.ActionSupport">
|
||||
<result type="freemarker">
|
||||
<param name="location">org/apache/struts2/views/freemarker/callActionFreeMarker2.ftl</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
</package>
|
||||
|
||||
<package name="sitegraph" namespace="/tutorial/sitegraph" extends="struts-default">
|
||||
|
||||
Reference in New Issue
Block a user