View Javadoc

1   /*
2    * $Id: TokenSessionStoreInterceptor.java 471756 2006-11-06 15:01:43Z husted $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.interceptor;
22  
23  import java.util.Map;
24  
25  import javax.servlet.http.HttpServletRequest;
26  
27  import org.apache.struts2.ServletActionContext;
28  import org.apache.struts2.util.InvocationSessionStore;
29  import org.apache.struts2.util.TokenHelper;
30  
31  import com.opensymphony.xwork2.ActionContext;
32  import com.opensymphony.xwork2.ActionInvocation;
33  import com.opensymphony.xwork2.Result;
34  import com.opensymphony.xwork2.util.ValueStack;
35  
36  
37  /***
38   * <!-- START SNIPPET: description -->
39   *
40   * This interceptor builds off of the {@link TokenInterceptor}, providing advanced logic for handling invalid tokens.
41   * Unlike the normal token interceptor, this interceptor will attempt to provide intelligent fail-over in the event of
42   * multiple requests using the same session. That is, it will block subsequent requests until the first request is
43   * complete, and then instead of returning the <i>invalid.token</i> code, it will attempt to display the same response
44   * that the original, valid action invocation would have displayed if no multiple requests were submitted in the first
45   * place.
46   *
47   * <p/>
48   *
49   * <b>NOTE:</b> As this method extends off MethodFilterInterceptor, it is capable of
50   * deciding if it is applicable only to selective methods in the action class. See
51   * <code>MethodFilterInterceptor</code> for more info.
52   *
53   * <!-- END SNIPPET: description -->
54   *
55   * <p/> <u>Interceptor parameters:</u>
56   *
57   * <!-- START SNIPPET: parameters -->
58   *
59   * <ul>
60   *
61   * <li>None</li>
62   *
63   * </ul>
64   *
65   * <!-- END SNIPPET: parameters -->
66   *
67   * <p/> <u>Extending the interceptor:</u>
68   *
69   * <p/>
70   *
71   * <!-- START SNIPPET: extending -->
72   *
73   * There are no known extension points for this interceptor.
74   *
75   * <!-- END SNIPPET: extending -->
76   *
77   * <p/> <u>Example code:</u>
78   *
79   * <pre>
80   * <!-- START SNIPPET: example -->
81   *
82   * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
83   *     &lt;interceptor-ref name="token-session/&gt;
84   *     &lt;interceptor-ref name="basicStack"/&gt;
85   *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
86   * &lt;/action&gt;
87   *
88   * &lt;-- In this case, myMethod of the action class will not
89   *        get checked for invalidity of token --&gt;
90   * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
91   *     &lt;interceptor-ref name="token-session&gt;
92   *         &lt;param name="excludeMethods"&gt;myMethod&lt;/param&gt;
93   *     &lt;/interceptor-ref name="token-session&gt;
94   *     &lt;interceptor-ref name="basicStack"/&gt;
95   *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
96   * &lt;/action&gt;
97   *
98   * <!-- END SNIPPET: example -->
99   * </pre>
100  *
101  */
102 public class TokenSessionStoreInterceptor extends TokenInterceptor {
103 
104     private static final long serialVersionUID = -9032347965469098195L;
105 
106     /* (non-Javadoc)
107      * @see org.apache.struts2.interceptor.TokenInterceptor#handleInvalidToken(com.opensymphony.xwork2.ActionInvocation)
108      */
109     protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
110         ActionContext ac = invocation.getInvocationContext();
111 
112         HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
113         String tokenName = TokenHelper.getTokenName();
114         String token = TokenHelper.getToken(tokenName);
115 
116         Map params = ac.getParameters();
117         params.remove(tokenName);
118         params.remove(TokenHelper.TOKEN_NAME_FIELD);
119 
120         if ((tokenName != null) && (token != null)) {
121             ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token);
122 
123             if (savedInvocation != null) {
124                 // set the valuestack to the request scope
125                 ValueStack stack = savedInvocation.getStack();
126                 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
127 
128                 Result result = savedInvocation.getResult();
129 
130                 if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
131                     result.execute(savedInvocation);
132                 }
133 
134                 // turn off execution of this invocations result
135                 invocation.getProxy().setExecuteResult(false);
136 
137                 return savedInvocation.getResultCode();
138             }
139         }
140 
141         return INVALID_TOKEN_CODE;
142     }
143 
144     /* (non-Javadoc)
145      * @see org.apache.struts2.interceptor.TokenInterceptor#handleValidToken(com.opensymphony.xwork2.ActionInvocation)
146      */
147     protected String handleValidToken(ActionInvocation invocation) throws Exception {
148         // we know the token name and token must be there
149         String key = TokenHelper.getTokenName();
150         String token = TokenHelper.getToken(key);
151         InvocationSessionStore.storeInvocation(key, token, invocation);
152 
153         return invocation.invoke();
154     }
155 }