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 }