1

我创建了一个拦截器,我想在某些操作中映射到某些特定方法,并且我不想干扰现有代码:

struts.xml

<package name="francis" namespace="/francis" extends="struts-default,json-default">
    <interceptors>             
        <interceptor name="authentication" class="main.java.com.commdel.commons.struts2.interceptors.AuthenticationInterceptor"/>            
        <interceptor name="authorization" class="main.java.com.commdel.commons.struts2.interceptors.SecurityInterceptor"/>

自定义拦截器csrf

        <interceptor name="csrf" class="main.java.com.commdel.commons.struts2.interceptors.CsrfTokenInterceptor"/>           
        
        <interceptor-stack name="commonStack">
            <interceptor-ref name="authentication"/>
            <interceptor-ref name="authorization"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
     </interceptors> 
     <default-interceptor-ref name="commonStack"/>
    <global-results>
          <result name="error" type="velocity">/results/velocity/common/globalerror.vm</result>  
          <result name="AUTHORIZATIONERROR" type="velocity">/results/velocity/common/sessionError.vm</result>                        
      </global-results>

映射csrf到一些动作:

    <action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
        <interceptor-ref name="csrf"/>
    </action>
</package> 
4

2 回答 2

0

您似乎认为默认拦截器堆栈适用于所有操作,并且您为单个操作指定的最终拦截器已添加到默认堆栈中。他们不是。

默认堆栈是用于未指定任何堆栈(或单个拦截器,如您的情况)的所有操作的堆栈。

如果你想添加一个拦截器,那么还要指定它应该添加到的堆栈,

<action name="addUpdateClaimHeadMetronic" 
       class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" 
      method="addUpdateClaimHead">

    <interceptor-ref name="commonStack"/>
    <interceptor-ref name="csrf"/>
</action>

或定义一个新堆栈并使用它:

<interceptor-stack name="commonStack">
    <interceptor-ref name="authentication"/>
    <interceptor-ref name="authorization"/>
    <interceptor-ref name="defaultStack"/>
</interceptor-stack>

<interceptor-stack name="csrfStack">
    <interceptor-ref name="authentication"/>
    <interceptor-ref name="authorization"/>
    <interceptor-ref name="defaultStack"/>
    <interceptor-ref name="csrf"/>
</interceptor-stack>

....

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

....

<action name="addUpdateClaimHeadMetronic" 
       class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" 
      method="addUpdateClaimHead">

    <interceptor-ref name="csrfStack"/>
</action>

请注意,如果您有很多共享辅助拦截器堆栈配置的操作,则第一种方法违反 DRY,并且仅当您的拦截器适合放置在第一个或最后一个时才可以使用它。如果你在中间需要它(例如 after param,但 before workflow),你必须通过分解 defaultStack 来定义一个堆栈,从struts-default.xml复制它。

于 2016-02-16T09:06:18.590 回答
0

如果您将自定义拦截器添加到操作配置中,例如

<action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
    <interceptor-ref name="csrf"/>
</action>

那么只有csrf拦截器将被配置到这个动作映射。commonStack即使您使用,其他拦截器也将被省略

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

Struts 允许覆盖不会使用 的动作配置default-interceptor-ref,如果您将自定义拦截器添加到动作映射中。通过覆盖操作配置,您可以使用一组自定义拦截器。

defaultStack如果您忘记在自定义操作映射中包含拦截器的所有引用,您可能会错过驱动 Struts2 框架的一些重要拦截器。

注意: Struts2 中的 拦截器在动作执行之前或之后为动作添加额外的功能。但是缺少一些重要的拦截器可能会破坏动作的执行。


如果您想添加对现有操作的自定义拦截器引用,那么您应该在您的操作映射之前或之后添加对默认堆栈的引用以及您的自定义拦截器,具体取决于您的代码。

<action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
    <interceptor-ref name="csrf"/>
    <interceptor-ref name="commonStack"/>
</action> 

注意: 拦截器是按照它们在 xml 配置中使用的顺序调用的。

于 2016-02-16T09:56:06.150 回答