1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.interceptor;
23
24 import java.util.Map;
25
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28
29 import org.apache.struts2.ServletActionContext;
30 import org.apache.struts2.util.InvocationSessionStore;
31 import org.apache.struts2.util.TokenHelper;
32
33 import com.opensymphony.xwork2.ActionContext;
34 import com.opensymphony.xwork2.ActionInvocation;
35 import com.opensymphony.xwork2.Result;
36 import com.opensymphony.xwork2.util.ValueStack;
37
38
39 /***
40 * <!-- START SNIPPET: description -->
41 *
42 * This interceptor builds off of the {@link TokenInterceptor}, providing advanced logic for handling invalid tokens.
43 * Unlike the normal token interceptor, this interceptor will attempt to provide intelligent fail-over in the event of
44 * multiple requests using the same session. That is, it will block subsequent requests until the first request is
45 * complete, and then instead of returning the <i>invalid.token</i> code, it will attempt to display the same response
46 * that the original, valid action invocation would have displayed if no multiple requests were submitted in the first
47 * place.
48 *
49 * <p/>
50 *
51 * <b>NOTE:</b> As this method extends off MethodFilterInterceptor, it is capable of
52 * deciding if it is applicable only to selective methods in the action class. See
53 * <code>MethodFilterInterceptor</code> for more info.
54 *
55 * <!-- END SNIPPET: description -->
56 *
57 * <p/> <u>Interceptor parameters:</u>
58 *
59 * <!-- START SNIPPET: parameters -->
60 *
61 * <ul>
62 *
63 * <li>None</li>
64 *
65 * </ul>
66 *
67 * <!-- END SNIPPET: parameters -->
68 *
69 * <p/> <u>Extending the interceptor:</u>
70 *
71 * <p/>
72 *
73 * <!-- START SNIPPET: extending -->
74 *
75 * There are no known extension points for this interceptor.
76 *
77 * <!-- END SNIPPET: extending -->
78 *
79 * <p/> <u>Example code:</u>
80 *
81 * <pre>
82 * <!-- START SNIPPET: example -->
83 *
84 * <action name="someAction" class="com.examples.SomeAction">
85 * <interceptor-ref name="tokenSession/>
86 * <interceptor-ref name="basicStack"/>
87 * <result name="success">good_result.ftl</result>
88 * </action>
89 *
90 * <-- In this case, myMethod of the action class will not
91 * get checked for invalidity of token -->
92 * <action name="someAction" class="com.examples.SomeAction">
93 * <interceptor-ref name="tokenSession>
94 * <param name="excludeMethods">myMethod</param>
95 * </interceptor-ref name="tokenSession>
96 * <interceptor-ref name="basicStack"/>
97 * <result name="success">good_result.ftl</result>
98 * </action>
99 *
100 * <!-- END SNIPPET: example -->
101 * </pre>
102 *
103 */
104 public class TokenSessionStoreInterceptor extends TokenInterceptor {
105
106 private static final long serialVersionUID = -9032347965469098195L;
107
108
109
110
111 protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
112 ActionContext ac = invocation.getInvocationContext();
113
114 HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
115 HttpServletResponse response = (HttpServletResponse) ac.get(ServletActionContext.HTTP_RESPONSE);
116 String tokenName = TokenHelper.getTokenName();
117 String token = TokenHelper.getToken(tokenName);
118
119 Map params = ac.getParameters();
120 params.remove(tokenName);
121 params.remove(TokenHelper.TOKEN_NAME_FIELD);
122
123 if ((tokenName != null) && (token != null)) {
124 ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token);
125
126 if (savedInvocation != null) {
127
128 ValueStack stack = savedInvocation.getStack();
129 Map context = stack.getContext();
130 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
131
132 ActionContext savedContext = savedInvocation.getInvocationContext();
133 savedContext.getContextMap().put(ServletActionContext.HTTP_REQUEST, request);
134 savedContext.getContextMap().put(ServletActionContext.HTTP_RESPONSE, response);
135 Result result = savedInvocation.getResult();
136
137 if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
138 synchronized (context) {
139 result.execute(savedInvocation);
140 }
141 }
142
143
144 invocation.getProxy().setExecuteResult(false);
145
146 return savedInvocation.getResultCode();
147 }
148 }
149
150 return INVALID_TOKEN_CODE;
151 }
152
153
154
155
156 protected String handleValidToken(ActionInvocation invocation) throws Exception {
157
158 String key = TokenHelper.getTokenName();
159 String token = TokenHelper.getToken(key);
160 InvocationSessionStore.storeInvocation(key, token, invocation);
161
162 return invocation.invoke();
163 }
164 }