From 7e4d1b45ea9d349d22a9995dd38c8a21f0321ef0 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Mon, 19 Dec 2016 18:51:04 +0100 Subject: [PATCH] WW-4725 Allows handle all redirection by MessageStoreInterceptor --- .../interceptor/MessageStoreInterceptor.java | 9 +++- .../MessageStorePreResultListener.java | 46 ++++++++++++------- .../apache/struts2/result/Redirectable.java | 8 ++++ .../result/ServletActionRedirectResult.java | 2 +- .../struts2/result/ServletRedirectResult.java | 2 +- .../MessageStorePreResultListenerTest.java | 12 +++-- .../json/JSONActionRedirectResult.java | 3 +- 7 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 core/src/main/java/org/apache/struts2/result/Redirectable.java diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java index f3e8cb5d2..5052df7f3 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java @@ -203,7 +203,10 @@ public class MessageStoreInterceptor extends AbstractInterceptor { before(invocation); LOG.trace("Registering listener to store messages before result will be executed"); - invocation.addPreResultListener(new MessageStorePreResultListener(this)); + MessageStorePreResultListener preResultListener = createPreResultListener(invocation); + preResultListener.init(this); + + invocation.addPreResultListener(preResultListener); String result = invocation.invoke(); @@ -212,6 +215,10 @@ public class MessageStoreInterceptor extends AbstractInterceptor { return result; } + protected MessageStorePreResultListener createPreResultListener(ActionInvocation invocation) { + return new MessageStorePreResultListener(); + } + /** * Handle the retrieving of field errors / action messages / field errors, which is * done before action invocation, and the operationMode is 'RETRIEVE'. diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java index 9b313a8fe..4df6591a6 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java @@ -26,8 +26,7 @@ import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ServletActionContext; -import org.apache.struts2.result.ServletActionRedirectResult; -import org.apache.struts2.result.ServletRedirectResult; +import org.apache.struts2.result.Redirectable; import java.util.Map; @@ -36,26 +35,25 @@ import java.util.Map; * just before result will be executed. It must be done that way as after result will be executed * HttpSession cannot be modified (response was already sent to browser). */ -class MessageStorePreResultListener implements PreResultListener { +public class MessageStorePreResultListener implements PreResultListener { private static final Logger LOG = LogManager.getLogger(MessageStorePreResultListener.class); - private MessageStoreInterceptor interceptor; + protected MessageStoreInterceptor interceptor; - public MessageStorePreResultListener(MessageStoreInterceptor interceptor) { + public void init(MessageStoreInterceptor interceptor) { this.interceptor = interceptor; } - @Override public void beforeResult(ActionInvocation invocation, String resultCode) { - boolean isCommitted = ServletActionContext.getResponse().isCommitted(); + boolean isCommitted = isCommitted(); if (isCommitted) { LOG.trace("Response was already committed, cannot store messages!"); return; } - boolean isInvalidated = ServletActionContext.getRequest().getSession(false) == null; + boolean isInvalidated = isInvalidated(); if (isInvalidated) { LOG.trace("Session was invalidated or never created, cannot store messages!"); return; @@ -69,15 +67,7 @@ class MessageStorePreResultListener implements PreResultListener { String reqOperationMode = interceptor.getRequestOperationMode(invocation); - boolean isRedirect = false; - try { - ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode); - if (resultConfig != null) { - isRedirect = ServletRedirectResult.class.isAssignableFrom(Class.forName(resultConfig.getClassName())); - } - } catch (Exception e) { - LOG.warn("Cannot read result!", e); - } + boolean isRedirect = isRedirect(invocation, resultCode); if (MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(reqOperationMode) || MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(interceptor.getOperationModel()) || @@ -97,4 +87,26 @@ class MessageStorePreResultListener implements PreResultListener { } } } + + protected boolean isCommitted() { + return ServletActionContext.getResponse().isCommitted(); + } + + protected boolean isInvalidated() { + return ServletActionContext.getRequest().getSession(false) == null; + } + + protected boolean isRedirect(ActionInvocation invocation, String resultCode) { + boolean isRedirect = false; + try { + ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode); + if (resultConfig != null) { + isRedirect = Redirectable.class.isAssignableFrom(Class.forName(resultConfig.getClassName())); + } + } catch (Exception e) { + LOG.warn("Cannot read result!", e); + } + return isRedirect; + } + } diff --git a/core/src/main/java/org/apache/struts2/result/Redirectable.java b/core/src/main/java/org/apache/struts2/result/Redirectable.java new file mode 100644 index 000000000..54fdf6581 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/result/Redirectable.java @@ -0,0 +1,8 @@ +package org.apache.struts2.result; + +/** + * Marking interface for results which perform browser redirection + */ +public interface Redirectable { + +} diff --git a/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java b/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java index 798e80982..5a4528e03 100644 --- a/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java +++ b/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java @@ -123,7 +123,7 @@ import java.util.List; * * @see ActionMapper */ -public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler { +public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler, Redirectable { private static final long serialVersionUID = -9042425229314584066L; diff --git a/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java b/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java index e8044167e..552ee049e 100644 --- a/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java +++ b/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java @@ -98,7 +98,7 @@ import static javax.servlet.http.HttpServletResponse.SC_FOUND; * * */ -public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler { +public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler, Redirectable { private static final long serialVersionUID = 6316947346435301270L; diff --git a/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java index e888a5527..9074bcb2a 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java @@ -54,7 +54,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase { // when MessageStoreInterceptor msi = new MessageStoreInterceptor(); - MessageStorePreResultListener listener = new MessageStorePreResultListener(msi); + MessageStorePreResultListener listener = new MessageStorePreResultListener(); + listener.init(msi); listener.beforeResult(mockActionInvocation, Action.SUCCESS); // then @@ -86,7 +87,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase { // when MessageStoreInterceptor msi = new MessageStoreInterceptor(); - MessageStorePreResultListener listener = new MessageStorePreResultListener(msi); + MessageStorePreResultListener listener = new MessageStorePreResultListener(); + listener.init(msi); listener.beforeResult(mockActionInvocation, Action.SUCCESS); // then @@ -98,7 +100,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase { MessageStoreInterceptor interceptor = new MessageStoreInterceptor(); interceptor.setOperationMode(MessageStoreInterceptor.AUTOMATIC_MODE); - MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor); + MessageStorePreResultListener listener = new MessageStorePreResultListener(); + listener.init(interceptor); Map sessionMap = new LinkedHashMap(); @@ -178,7 +181,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase { interceptor.setAllowRequestParameterSwitch(true); interceptor.setOperationMode(MessageStoreInterceptor.STORE_MODE); - MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor); + MessageStorePreResultListener listener = new MessageStorePreResultListener(); + listener.init(interceptor); Map sessionMap = new LinkedHashMap(); diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java index 4b8b94867..c3a92687f 100644 --- a/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java +++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONActionRedirectResult.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.result.Redirectable; import org.apache.struts2.result.ServletActionRedirectResult; /** @@ -24,7 +25,7 @@ import org.apache.struts2.result.ServletActionRedirectResult; *

* */ -public class JSONActionRedirectResult extends ServletActionRedirectResult { +public class JSONActionRedirectResult extends ServletActionRedirectResult implements Redirectable { private static final long serialVersionUID = 3107276294073879542L;