Explaining the Struts2 interceptor mechanism


The heart of Struts2 lies in its complex interceptor, which does almost 70% of the work. For example, the fileUpload interceptor that we used before to set the uploaded file to correspond to the three properties in the action instance, and the param interceptor that is used to set the http request parameters of the form page to the corresponding properties in the action, etc. In short, the role of interceptors throughout the Struts framework is quite significant, and this article will detail the following points about Struts interceptors.

  • The role of interceptors in Struts
  • Custom Interceptor Implementation Class
  • Configuring interceptors (includes configuring default interceptors)
  • Reference Interceptor
  • configure interception designate approach of interception utensil
  • interception ware interception sequential

one、 The role of interceptors in Struts In our web.xml, we configure a filter that implements delivering all requests to the StrutsPrepareAndExecuteFilter class. Once a request for any action is accepted, the class creates and initializes an ActionProxy instance that proxies the specific action, in which we can add any interceptor to do some additional operations before and after the execute method is executed, which will eventually call the execute method of the action instance and return the view result string for the user, and then the system will fetch the corresponding view page based on that view result string. The following diagram shows the relationship between interceptors and actions.

This is a typical AOP idea, when we define a package in Struts.xml, in most cases we inherit the struts-default file, so although we don't manually configure any interceptors in our own configuration file, the actions we create are intercepted and processed by many interceptors, just because the interceptors configured in struts-default are in effect. Struts has a lot of built-in interceptors, most of them are configured in the struts-default file, for a detailed description of the built-in interceptors you can refer to the official API, next we look at how to customize an interceptor.

II. Custom Interceptor Implementation Class To implement your own interceptor class simply implement the com.opensymphony.xwork2.interceptor.Interceptor interface, which has the following methods.

  public abstract void destroy();
  
  public abstract void init();
  
  public abstract String intercept(ActionInvocation paramActionInvocation)
    throws Exception;

init approach (located) at execute interception approach Previous Pullback, Mainly used to initialize some resources,destroy together withinit approach corresponds, (located) at interception callback before the instance is destroyed, It is mainly used for releasing ininit approach Resources opened in。intercept approach It's ours. interception approach, We can rewrite the approach to complete the analysis of theaction instantiated interception, should approach has aActionInvocation Parameters of type, This parameter internally references the specificaction instance object( If thataction And others. interception utensils), We can call this parameter of theinvoke approach Calling specificaction instantiatedexecute approach Or call the next interception utensil,intercept approach Return aString The type string represents the specific view page。 See a specific example below:

public class TestAction extends ActionSupport {

    public String execute(){
        System.out.println(" executeexecute approach......");
        return SUCCESS;
    }
}
public class MyIntercept implements Interceptor {

    public void init() {}
    public void destroy() {}

    public String intercept(ActionInvocation action) throws Exception{
        System.out.println(" interceptionaction commencement.......");
        String result = action.invoke();
        System.out.println(" interceptionaction close.......");
        return result;
    }
}

Configuration omitted interception utensils andTestAction code, The following screenshot shows the results of the above program run:

three、 Configuration and Reference Interceptor The above example defines a simple interceptor implementation class, we omitted the code in struts.xml to configure and reference the interceptor, this subsection will detail how to define and reference our custom implementation of the interceptor class in struts.xml.

through (a gap)struts-default.xml We can see it in, We use<interceptors> Element Definition interception utensilname and physical location of the pair, for example:

<interceptors>
    <interceptor name="test" class="MyPackage.TestAction"/>
    ......
    ......
</interceptors>

The above code defines an interceptor test, which corresponds to a specific class. Note that the element defining the interceptor, interceptors, and its children must be configured under a package.

The above only defines a interception ware and specific interception The mapping relationship between the ware implementation classes, But trying to implement a specificaction of interception Need to use the element<interceptor-ref> depending onname attribute value references an already-defined interception utensil。 for example:

<action name="test" class="MyPackage.TestAction">
    <interceptor-ref name="test"/>
    <result name="success">/index.jsp</result>
    ......
    ......
</action>

As the above code demonstrates, This element is used to reference an already defined interception utensil, and the element appears in the specificaction inside (part, section), indicates that theaction has atest interception utensil。 The above code implements the use of a single interception Definition and reference of ware, In fact, for interception warehouse( pile interception ware sets) To say that the configuration is similar。 Define a interception The code for the ware stack is as follows:

<interceptor-stack name=" interception warehouse name">
    interceptor-ref name=" interception purifiers"/>
    interceptor-ref name=" interception ware two"/>
    interceptor-ref name=" interception tool three"/>
    .....
</interceptor-stack>

Referencing an interceptor stack would make little difference: the

interceptor-ref name=" interception warehouse name"/>

And of course we can also get the best out of it by

<default-interceptor-ref name=" interception utensil name"/>

Configuring a default interceptor or interceptor stack will invoke that default interceptor if no interceptor is explicitly specified for an action under that package, otherwise the default interceptor will fail if an interceptor is explicitly configured.

four、 because ofAction specify approachconfigure interception utensil By default, We provideaction Configured interception purifiers, should interception The apparatus will interception shouldaction In all the approach, This can sometimes get us into trouble., definitelystruts Provide us withAPI Used to target a specific approachconfigure interception utensil。 There is an abstract class involved here:MethodFilterInterceptor。 This class actually implements theInterceptor And complete with some default implementations, Let's take a brief look at the code involved:

public abstract class MethodFilterInterceptor
  extends AbstractInterceptor
{
// shouldset The set holds the interception apparatus is not required interception of all approach
  protected Set<String> excludeMethods = Collections.emptySet();
  // shouldset The set holds all of the data for that interception apparatus needs interception of approach
  protected Set<String> includeMethods = Collections.emptySet();
  // an omissiongetter,setter approach
  
  // use in interceptionaction entrance
  public String intercept(ActionInvocation invocation)
    throws Exception
  {
    if (applyInterceptor(invocation)) {
      return doIntercept(invocation);
    }
    return invocation.invoke();
  }
  
  // Determines the current call required toaction processing logic approach Does it need to be this interception utensil interception
  protected boolean applyInterceptor(ActionInvocation invocation)
  {
    String method = invocation.getProxy().getMethod();
    
    boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(this.excludeMethods, this.includeMethods, method);
    if ((this.log.isDebugEnabled()) && 
      (!applyMethod)) {
      this.log.debug("Skipping Interceptor... Method [" + method + "] found in exclude list.", new String[0]);
    }
    return applyMethod;
  }
  
  // This is what we need to rewrite approach, The specific roles are described below
  protected abstract String doIntercept(ActionInvocation paramActionInvocation)
    throws Exception;
}

As you can see from the above code, the abstract class implements the Interceptor interface and completes the basic implementation. In addition, the class provides two collections to store all the methods that need to be intercepted by the interceptor and all the methods that do not need to be intercepted. The interceptor entry intercept will first determine whether the logic processing method in the action instance of the request needs to be intercepted by the interceptor, and if it needs to be intercepted, then doIntercept our own implementation of the interceptor logic will be called. Otherwise the invoke method is called directly to execute the processing logic. So in general, we just need to override the doIntercept method to complete the core processing of the interceptor.

One thing to note here, of course, is that, Used to determine the processing logic of the current request approach Does it need to be that interception utensil interception of approachapplyInterceptor It's inintercept checked in, That is to say, in executedoIntercept approach prior toexcludeMethods harmonyincludeMethods should have been initialized with the value of。 So we're indoIntercept It is useless to assign values to these two properties again in, Because the calibration is already done。 Generally, we are instruts.xml Assigning values to these two properties in, Because the profile was loaded first。 Let's look at an example:

 // Customize an interceptor
public class MyIntercept extends MethodFilterInterceptor {

    protected  String doIntercept(ActionInvocation action)
            throws Exception{
        System.out.println(" interception commencement......");
        String result = action.invoke();
        System.out.println(" interception close......");
        return result;
    }
}
// Reference the interception and specify that it is not required interception of approach
<action name="test" class="MyPackage.TestAction">
    <interceptor-ref name="test">
                <param name="excludeMethods">execute</param>
    </interceptor-ref>
    <result name="success">/index.jsp</result>
</action>

Below we see screenshots of the results of the run.

Obviously we specified that the interceptor does not use the intercept method execute, and of course the result is displayed as we would like it to be. If we change the above struts.xml to read.

<action name="test" class="MyPackage.TestAction">
    <interceptor-ref name="test">
        <param name="includeMethods">execute</param>
    </interceptor-ref>
    <result name="success">/index.jsp</result>
</action>

We specify that the execute method is required to be intercepted by the interceptor, and the following screenshot of the result of the run.

Of course if you need to specify multiple methods to be blocked or not to be blocked, you can use English commas to separate the methods, e.g.

<param name="includeMethods"> approach one, approach Two, approach three</param>

Finally, there is one more point: If one approach both were placedincludeMethods was also placedexcludeMethods middle, Then the framework will be selected interception should approach。

V. Some other details about the interceptor mechanism interception ware execute The order is followed Reference Interceptor The order of the, For example, we define two interception utensil:

<action name="test" class="MyPackage.TestAction">
    <interceptor-ref name="test"/>
    <interceptor-ref name="test2"/>
    <result name="success">/index.jsp</result>
</action>

This means that after the first interceptor intercepts the action, the invoke method is called, and if there are other interceptors the next interceptor is called, nesting layer upon layer, ending with the outermost interceptor.

In the above example we used the param parameter to assign a value to the includeMethods property in the interceptor class, but if it is an interceptor stack how do we have to assign a value to one of the specific interceptor properties?

<interceptor-ref name=" interception warehouse">
    <param name=" interception purifiers. property name"> property value</param>
</interceptor-ref>

So far, we briefly understand the knowledge about struts2 interceptors, if you need a deep understanding of the specific project to experience, the summary of where not, hope to congratulate!


Recommended>>
1、Hand mahjong cheat hand mahjong hang hand mahjong auxiliary seethrough software universal version
2、Beautyrests fuselage ads exposed flight copromotion confirmed
3、Nextgeneration Golf with selfdriving and LCD touchscreen to be replaced next year
4、249 Google AI camera Clips hits GoogleStore for March shipping
5、Journaling the quality of input

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号