为某些操作添加自定义拦截器

Adding a custom interceptor for some actions

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

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> 

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

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

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

<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,并且只有当您的拦截器适合放置在第一个或最后一个时才可以使用它。如果你在中间需要它(例如,在 param 之后,但在 workflow 之前),你必须通过分解 defaultStack 来定义一个堆栈,从 struts-default.xml.

复制它

如果像

这样的动作配置添加自定义拦截器
<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 的动作配置,如果您将自定义拦截器添加到动作映射。通过覆盖操作配置,您可以使用一组自定义拦截器。

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

注意: interceptors in Struts2 在执行操作之前或之后向操作添加附加功能。但是缺少一些重要的拦截器可能会中断操作执行。


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

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

注意: interceptors 按它们在 xml 配置中使用的顺序调用。