为某些动作编写自定义拦截器,而不是工作

时间:2016-02-16 06:51:11

标签: java configuration struts2 interceptor interceptorstack

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

<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> 

2 个答案:

答案 0 :(得分: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,并且仅当您的Interceptor可以作为第一个或最后一个放置时才能使用它。如果你需要它在中间(例如,在param之后,但在workflow之前),你必须通过爆炸defaultStack来定义一个堆栈,从struts-default.xml复制它。

答案 1 :(得分:0)

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

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

然后只有csrf拦截器将配置到此操作配置。这样Struts允许不使用默认的拦截器引用,但是使用自定义集覆盖操作配置。但是这样你可能会遗漏驱动Struts2框架的defaultStack中的一些重要拦截器。

您已使用自定义拦截器堆栈作为默认拦截器引用,该引用包含在操作配置中,用于不覆盖其拦截器的操作。

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

请注意,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配置元素中使用的顺序调用。