Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The framework makes it easy to share solutions to these concerns using an "Interceptor" strategy. When you request a resource that maps to an "action", the framework invokes the Action object. But, before the Action is executed, the invocation can be intercepted by another object. After the Action executes, the invocation could be intercepted again. Unsurprisingly, we call these objects "Interceptors."

Table of Contents
minLevel2

Understanding Interceptors

...

Code Block
xml
titlestruts.xml
xml

<package name="default" extends="struts-default">
   <interceptors>
       <interceptor name="timer" class=".."/>
       <interceptor name="logger" class=".."/>
   </interceptors>

   <action name="login"
      class="tutorial.Login">
        <interceptor-ref name="timer"/>
        <interceptor-ref name="logger"/>
         <result name="input">login.jsp</result>
         <result name="success"
            type="redirectAction">/secure/home</result>
   </action>
</package>

...

Code Block
xml
titlestruts.xml
xml

<package name="default" extends="struts-default">
   <interceptors>
        <interceptor name="timer" class=".."/>
        <interceptor name="logger" class=".."/>
        <interceptor-stack name="myStack">
           <interceptor-ref name="timer"/>
           <interceptor-ref name="logger"/>
        </interceptor-stack>
    </interceptors>

<action name="login"
     class="tutuorial.Login">
         <interceptor-ref name="myStack"/>
         <result name="input">login.jsp</result>
         <result name="success"
             type="redirectAction">/secure/home</result>
</action>
</package>

...

Wiki Markup
{snippet:id=javadoc|javadoc=true|url=com.opensymphony.xwork2.interceptor/.MethodFilterInterceptor.java}

...

Method 1:

Code Block
xml
xml

<action name="myAction" class="myActionClass">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="alias"/>
    <interceptor-ref name="params"/>
    <interceptor-ref name="servletConfig"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="i18n"/>
    <interceptor-ref name="chain"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="fileUpload"/>
    <interceptor-ref name="staticParams"/>
    <interceptor-ref name="params"/>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation">
        <param name="excludeMethods">myValidationExcudeMethod</param>
    </interceptor-ref>
    <interceptor-ref name="workflow">
        <param name="excludeMethods">myWorkflowExcludeMethod</param>
    </interceptor-ref>
</action>

Method 2:

Code Block
xml
xml

<action name="myAction" class="myActionClass">
    <interceptor-ref name="defaultStack">
        <param name="validation.excludeMethods">myValidationExcludeMethod</param>
        <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>
    </interceptor-ref>
</action>

...

In the second method, the interceptor-ref refers to an existing interceptor-stack, namely defaultStack in this example, and override the validator and workflow interceptor excludeMethods attribute. Note that in the param tag, the name attribute contains a dot (.) the word before the dot(.) specifies the interceptor name whose parameter is to be overridden and the word after the dot (.) specifies the parameter itself. The syntax is as follows:

Code Block

   <interceptor-name>.<parameter-name>

...

Method 3:

Code Block
xml
xml

<interceptors>
    <interceptor-stack name="parentStack">
        <interceptor-ref name="defaultStack">
            <param name="params.excludeParams">token</param>
        </interceptor-ref>
    </interceptor-stack>
</interceptors>

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

...

Parameters override are not inherited in interceptors, meaning that the last set of overridden parameters will be used. For example, if a stack overrides the parameter "defaultBlock" for the "postPrepareParameterFilter" interceptor as:

Code Block
xml
xml

<interceptor-stack name="parentStack">
  <interceptor-ref name="postPrepareParameterFilter">
    <param name="defaultBlock">true</param>
  </interceptor-ref>
</interceptor-stack>

and an action overrides the "allowed" for "postPrepareParameterFilter":

Code Block
xml
xml

<package name="child2" namespace="/child" extends="parentPackage">
  <action name="list" class="SomeAction">
    <interceptor-ref name="parentStack">
      <param name="postPrepareParameterFilter.allowed">myObject.name</param>
    </interceptor-ref>
  </action>
</package>

...

Interceptors provide an excellent means to wrap before/after processing. The concept reduces code duplication (think AOP).

Code Block
xml
xml

<interceptor-stack name="xaStack">
  <interceptor-ref name="thisWillRunFirstInterceptor"/>
  <interceptor-ref name="thisWillRunNextInterceptor"/>
  <interceptor-ref name="followedByThisInterceptor"/>
  <interceptor-ref name="thisWillRunLastInterceptor"/>
</interceptor-stack>

...

Interceptors implementing com.opensymphony.xwork2.interceptor.PreResultListener will run after the Action executes but before the Result executes.

Code Block

thisWillRunFirstInterceptor
  thisWillRunNextInterceptor
    followedByThisInterceptor
      thisWillRunLastInterceptor
        MyAction1
        MyAction2 (chain)
        MyPreResultListener
        MyResult (result)
      thisWillRunLastInterceptor
    followedByThisInterceptor
  thisWillRunNextInterceptor
thisWillRunFirstInterceptor

...