...
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."
Understanding Interceptors
...
Code Block |
---|
|
<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 |
---|
|
<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 |
---|
|
<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 |
---|
|
<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 |
---|
|
<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 |
---|
|
<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 |
---|
|
<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 |
---|
|
<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
|
...