【问题标题】:Use of Token with Struts在 Struts 中使用 Token
【发布时间】:2015-01-19 14:33:10
【问题描述】:

当我在我的应用程序中单击两次链接时遇到问题,我完成了 2 次调用并且页面刷新了两次,并且发生了一些错误。

所以我决定使用令牌会话拦截器来防止这个错误。

我正在尝试在我的应用程序中添加 struts 2 tokenSession 拦截器,但我遇到了问题。

我已将此拦截器与所有其他拦截器一起添加:

<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>

现在,我的操作看起来像:

<action name="SC002AfficherTestSeuil!*" method="{1}" class="fr.edf.mpv2.castor.actions.surveillance.SC002AfficherTestSeuilAction">
        <interceptor-ref name="tokenSession"></interceptor-ref>
        <interceptor-ref name="mpoStack"></interceptor-ref>
        <result name="input">/jsp/fr/edf/mpv2/castor/surveillance/SC002__afficherLesTestsDeSeuil.jsp</result>
        <result name="PAGE_SC002_afficherLesTestsDeSeuil">/jsp/fr/edf/mpv2/castor/surveillance/SC002__afficherLesTestsDeSeuil.jsp</result>
    </action>

我的页面包含一个列表框和一个按钮名称“显示”

当我在列表框中选择项目时,用户单击显示按钮并完成 ajax 调用。

我进入public class TokenSessionStoreInterceptor extends TokenInterceptor的方法

喜欢:

 protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
    ActionContext ac = invocation.getInvocationContext();

    HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
    HttpServletResponse response = (HttpServletResponse) ac.get(ServletActionContext.HTTP_RESPONSE); 
    String tokenName = TokenHelper.getTokenName();
    String token = TokenHelper.getToken(tokenName);

    Map params = ac.getParameters();
    params.remove(tokenName);
    params.remove(TokenHelper.TOKEN_NAME_FIELD);

    if ((tokenName != null) && (token != null)) {
        ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token);

        if (savedInvocation != null) {
            // set the valuestack to the request scope
            ValueStack stack = savedInvocation.getStack();
            Map context = stack.getContext();
            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

            ActionContext savedContext = savedInvocation.getInvocationContext();
            savedContext.getContextMap().put(ServletActionContext.HTTP_REQUEST, request);
            savedContext.getContextMap().put(ServletActionContext.HTTP_RESPONSE, response);
            Result result = savedInvocation.getResult();

            if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
                synchronized (context) {
                    result.execute(savedInvocation);
                }
            }

            // turn off execution of this invocations result
            invocation.getProxy().setExecuteResult(false);

            return savedInvocation.getResultCode();
        }
    }

    return INVALID_TOKEN_CODE;
}

我不明白为什么,但是Result result = savedInvocation.getResult();这一行总是返回null,所以如果你阅读struts代码;我的操作从未完成,我的页面也从未刷新(请记住,这是一个 ajax 调用,因此只需要刷新页面的一部分)。

有人可以帮我理解为什么我的结果为空吗?我是不是忘记了配置中的某些内容?

非常感谢

编辑 #1 => 添加 mpoStack

<interceptor-stack name="mpoStack">
            <interceptor-ref name="exception" />
            <interceptor-ref name="alias" />
            <interceptor-ref name="servletConfig" />
            <interceptor-ref name="prepare" />
            <interceptor-ref name="i18n" />
            <interceptor-ref name="chain" />
            <!--<interceptor-ref name="debugging" />-->
            <!--<interceptor-ref name="profiling" />-->
            <!-- Stack d'interceptor sécurité de Marco Polo - Start -->
            <interceptor-ref name="securiteStack" >

            </interceptor-ref>
            <!-- Stack d'interceptor sécurité de Marco Polo - End -->
            <interceptor-ref name="fileUpload" />
            <interceptor-ref name="checkbox" />
            <interceptor-ref name="staticParams" />
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*</param>
            </interceptor-ref>
            <!--<interceptor-ref name="conversionError" />-->
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse,execute,retour,annuler</param>
            </interceptor-ref>
            <interceptor-ref name="jsonValidation"/>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse,execute,retour,annuler</param>
            </interceptor-ref>
        </interceptor-stack>
        <interceptor-stack name="mpoStackApplet">
            <interceptor-ref name="alias" />
            <interceptor-ref name="servletConfig" />
            <interceptor-ref name="prepare" />
            <interceptor-ref name="chain" />
            <interceptor-ref name="securiteStack" />
        </interceptor-stack>
        <!-- QC#3040 PATROL : web.log : Infinite recursion detected -->
        <interceptor-stack name="ErrorStack">
             <interceptor-ref name="exception" />
            <interceptor-ref name="alias" />
            <interceptor-ref name="servletConfig" />
            <interceptor-ref name="prepare" />
            <interceptor-ref name="i18n" />
            <interceptor-ref name="chain" />
            <interceptor-ref name="fileUpload" />
            <interceptor-ref name="checkbox" />
            <interceptor-ref name="staticParams" />
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*</param>
            </interceptor-ref>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse,execute,retour,annuler</param>
            </interceptor-ref>
            <interceptor-ref name="jsonValidation"/>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse,execute,retour,annuler</param>
            </interceptor-ref>
        </interceptor-stack>
    </interceptors>

    <default-interceptor-ref name="mpoStack" />

【问题讨论】:

  • 你也可以显示你的 mpoStack 定义吗?
  • 尝试做一个有效的token,这段代码不会被调用。
  • @AndreaLigios => 我已经编辑我的答案以添加 mpoStack ;)
  • @RomanC => 为什么它是一个有效的令牌?我不明白?你能解释一下吗?谢谢
  • 您发布了处理无效令牌的代码。删除此代码,或者如果令牌有效,则不应调用此方法。如果此拦截器已使用该令牌,则该令牌无效。

标签: java ajax struts2 token


【解决方案1】:

显然是Issue WW-3415(本身与Issue WW-3865Issue WW-3895相关)。

如果是这种情况,您可以尝试移至 2.3.20,这是第一个已修复该问题的版本。

或者,您可以尝试第一个问题的 OP 提出的解决方法,更改

return savedInvocation.getResultCode();

进入

// Checks if the saved invocation has been executed as of now. 
// If not it gets executed again.
if(savedInvocation.isExecuted()) { 
    return savedInvocation.getResultCode();  
} else { 
    return savedInvocation.invoke(); 
}

【讨论】:

  • 好的,我现在不能测试,但是当我测试这个时,我验证或不验证你的答案;)谢谢
  • 您好,不,因为问题最终不在这里,感谢您的帮助,因为如果我遇到这个问题,很高兴知道您的回答;)
  • 嗯。如果您能找到解决方案,请随时回答您自己的问题,以帮助未来的访问者。如果你觉得它有用,也可以考虑支持这个答案
【解决方案2】:

最后,问题不是我调用 invalidtoken 的原因,而是就像 Roman C 在评论中所说的那样,为什么我此时没有获得有效的令牌。所以我已经更正了我的代码来处理有效的令牌,现在一切正常。

【讨论】:

    猜你喜欢
    • 2012-12-19
    • 2011-03-22
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多