mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Fix issue introduced with earlier WW-4873 fix:
- Fixes error 500 processing failures for double-submit results with TokenSessionStoreInterceptor processing - Fix to InvocationSessionStore, new unit test confirming fix in InvocationSessionStoreTest - Minor whitespace fix to TokenSessionStoreInterceptor
This commit is contained in:
@@ -126,11 +126,12 @@ public class TokenSessionStoreInterceptor extends TokenInterceptor {
|
||||
params.remove(tokenName);
|
||||
params.remove(TokenHelper.TOKEN_NAME_FIELD);
|
||||
|
||||
String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(tokenName);
|
||||
String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(tokenName);
|
||||
ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(sessionTokenName, token);
|
||||
|
||||
if (savedInvocation != null) {
|
||||
// set the valuestack to the request scope
|
||||
// Note: loadInvocation() restored invocation's PageContext (as savedInvocation's will already be closed)
|
||||
ValueStack stack = savedInvocation.getStack();
|
||||
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
|
||||
|
||||
@@ -158,8 +159,8 @@ public class TokenSessionStoreInterceptor extends TokenInterceptor {
|
||||
// we know the token name and token must be there
|
||||
String key = TokenHelper.getTokenName();
|
||||
String token = TokenHelper.getToken(key);
|
||||
String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(key);
|
||||
InvocationSessionStore.storeInvocation(sessionTokenName, token, invocation);
|
||||
String sessionTokenName = TokenHelper.buildTokenSessionAttributeName(key);
|
||||
InvocationSessionStore.storeInvocation(sessionTokenName, token, invocation);
|
||||
|
||||
return invocation.invoke();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2.util;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
@@ -57,9 +58,22 @@ public class InvocationSessionStore {
|
||||
|
||||
ActionInvocation savedInvocation = null;
|
||||
if (invocationContext.invocation != null) {
|
||||
// WW-5026 - Preserve the previous PageContext (even if null) and restore it to the
|
||||
// ActionContext after loading the savedInvocation context. The saved context's PageContext
|
||||
// would already be closed at this point (causing failures if used for output).
|
||||
final ActionContext savedActionContext;
|
||||
final ActionContext previousActionContext;
|
||||
savedInvocation = invocationContext.invocation;
|
||||
ActionContext.setContext(savedInvocation.getInvocationContext());
|
||||
ActionContext.getContext().setValueStack(savedInvocation.getStack());
|
||||
savedActionContext = savedInvocation.getInvocationContext();
|
||||
previousActionContext = ActionContext.getContext();
|
||||
ActionContext.setContext(savedActionContext);
|
||||
savedActionContext.setValueStack(savedInvocation.getStack());
|
||||
savedActionContext.setValueStack(savedInvocation.getStack());
|
||||
if (previousActionContext != null) {
|
||||
savedActionContext.put(ServletActionContext.PAGE_CONTEXT, previousActionContext.get(ServletActionContext.PAGE_CONTEXT));
|
||||
} else {
|
||||
savedActionContext.put(ServletActionContext.PAGE_CONTEXT, null);
|
||||
}
|
||||
}
|
||||
|
||||
return savedInvocation;
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.struts.mock.MockPageContext;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
|
||||
|
||||
/**
|
||||
@@ -100,6 +102,35 @@ public class InvocationSessionStoreTest extends StrutsInternalTestCase {
|
||||
assertNull(savedInvocation);//Currently we don't support invocation restore from serialized session
|
||||
}
|
||||
|
||||
public void testStoreAndLoadPreservesPageContext() {
|
||||
ActionContext actionContext = ActionContext.getContext();
|
||||
|
||||
// Create mock PageContext to put with the saved context (simulating a PageContext previously
|
||||
// used and closed after generating JSP output).
|
||||
MockPageContext mockSavedPageContext = new MockPageContext();
|
||||
actionContext.put(ServletActionContext.PAGE_CONTEXT, mockSavedPageContext);
|
||||
assertEquals(mockSavedPageContext, ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT));
|
||||
|
||||
InvocationSessionStore.storeInvocation(INVOCATION_KEY, TOKEN_VALUE, invocation);
|
||||
|
||||
ActionContext actionContext2 = new ActionContext(new HashMap<String, Object>());
|
||||
actionContext2.setSession(session);
|
||||
ActionContext.setContext(actionContext2);
|
||||
assertEquals(actionContext2, ActionContext.getContext());
|
||||
|
||||
// Create mock PageContext to put with the current context (simulating a PageContext
|
||||
// associated with the current (active) process flow). In real-world processing it
|
||||
// will usually be null, but if non-null it should be preserved/restored upon load of the
|
||||
// saved context.
|
||||
MockPageContext mockPreviousPageContext = new MockPageContext();
|
||||
actionContext2.put(ServletActionContext.PAGE_CONTEXT, mockPreviousPageContext);
|
||||
assertEquals(mockPreviousPageContext, ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT));
|
||||
|
||||
InvocationSessionStore.loadInvocation(INVOCATION_KEY, TOKEN_VALUE);
|
||||
assertEquals(actionContext, ActionContext.getContext());
|
||||
assertEquals(mockPreviousPageContext, ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT));
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
stack = ActionContext.getContext().getValueStack();
|
||||
|
||||
Reference in New Issue
Block a user