Struts2 (vi) Interceptor mechanism

Source: Internet
Author: User


Interceptor Overview

An interceptor is a set of objects that dynamically intercept action calls. The handler code for the interceptor can be defined before or after the action is executed. At the same time, the interceptor can intercept the execution of an action. Interceptors can encapsulate some common functionality into reusable forms for use by one action or multiple actions.



The interceptor must be stateless because struts 2 cannot guarantee that an instance is created for each request or action, so if the interceptor has a status, it can cause concurrency problems. Do not use anything outside of the actioninvocation provided by the API.

Conceptually, interceptors is similar to the filters or JDKs proxy class of a servlet. Struts2 can be understood as an empty container, and a large number of built-in interceptors complete most of the framework's operations. For example, the params interceptor is responsible for parsing the parameters of the HTTP request and setting the action's properties The Servlet-config interceptor directly passes the HttpServletRequest instance and HttpServletResponse instance in the HTTP request to the Action;fileupload interceptor responsible for parsing the file fields in the request parameters. and set a file field to the three properties of the action, and so on. These common operations are done through the STRUTS2 built-in interceptors.

The Struts2 interceptor is pluggable, and if you need to use an interceptor, you only need to apply the interceptor to the configuration file, and if you do not use the interceptor, you simply cancel the interceptor in the configuration file without redeploying the app.

Struts2 interceptors are managed by configuration files such as Struts-default.xml and Struts.xml, and developers can easily expand their interceptors.

As mentioned earlier, there are some common logic in development, such as parsing request parameters, type conversion, encapsulating request parameters into DTOs (Data Transfer Object), performing input validation, parsing file fields in file upload forms, preventing multiple submissions of forms, and so on. STRUTS2 defines the work functions that most core controllers need to complete, each of which completes a function. These interceptors are freely selectable and flexibly assembled (even without struts2 of any interceptors), requiring which interceptors need only be specified in the Struts.xml file.

When you configure an action in a struts.xml file, the Struts-default package is inherited in the package, and a large number of common-use interceptors within the bundle will work.

<packagename="Default"extends="Struts-default"> <interceptors> <interceptorname="Timer" class=".."/> <interceptorname="Logger" class=".."/> </interceptors> <actionname="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>

Define the core filter in the Web. xml file.

<!--define STRUTS2 core filter --    <filter>        <filter-name>Struts2</filter-name>        <filter-class>Org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>    </filter>    <!--Let Struts2 's core filter intercept all action requests- -    <filter-mapping>        <filter-name>Struts2</filter-name>        <url-pattern>*.action</url-pattern>    </filter-mapping>

When Strutsprepareandexecutefilter intercepts a user request, a large number of interceptors will process the user request before invoking the method of the user-developed action instance to process the request. The relationship between the interceptor and the action is as shown.



Struts2 built-in interceptors

A large number of interceptors are built in the STRUTS2, These interceptors are configured in the form of a Name-class pair in the Struts-default.xml file, where name is the name of the Interceptor, which is the only indication of the use of the interceptor at a later time, and class specifies the implementation class for the Interceptor, and the program-defined package inherits the STRUTS2 default Stru Ts-default package, you can use the interceptor defined within the package without having to define the interceptor yourself.







Custom Interceptors

Built-in interceptors implement most of the functionality of STRUTS2, and most of the common features of Web applications can be done directly using these built-in interceptors, but there are some common related functions related to system logic that are implemented by custom interceptors.

Interceptor Interface

To develop a custom interceptor class, to implement the Com.opensymphony.xwork2.interceptor.Interceptor interface, the definition code for this interface is as follows.

public   interface  interceptor  extends  serializable     { //the callback method before destroying the interceptor  void  Destroy ();    //initialize the Interceptor's callback method       void  init ();    //Interceptor implements the logical method of interception  String Intercept (actioninvocation invocation) throws  Exception;}  


After the interceptor is instantiated, the init () method is called back before it is executed. The init () method of each interceptor executes only once. So the method body is mainly used to initialize resources, such as database connection.

destroy () corresponds to the init () method, and the system will callback the Interceptor's destroy method to destroy the resources opened in the Init () method before the interceptor instance is destroyed.

The inercept (actioninvocation invocation) method is a blocking action that the user needs to implement, like the Execute method of the action, and the Intercept method returns a string as a logical view. If the method returns a string directly, the system jumps to the actual view resource corresponding to the logical view and does not invoke the intercepted action. The Actioninvocation parameter of the method contains the action reference being intercepted, which can be transferred to the next interceptor by invoking the Invoke method of the parameter, or to the Execute method of the action.

Abstractinterceptor class

The Abstractinterceptor class implements the Interceptor interface.





The Abstractinterceptor class provides an empty implementation of the Init () and Destory () methods, which can be implemented without the need to open resources if the implemented interceptors do not require them.



defining and using interceptors

Customizing an interceptor requires three steps:

1. Customize a class that implements the Interceptor interface (or inherits from Abstractinterceptor).

2. Register the Interceptor defined in the previous step in Strutx.xml.

3. Refer to the above-defined interceptor in the action you need to use, and for convenience, you can define the interceptor as the default interceptor so that all actions are intercepted by the interceptor without special notice.

Custom Interceptors

ImportCom.opensymphony.xwork2.ActionInvocation;ImportCom.opensymphony.xwork2.interceptor.AbstractInterceptor;Importjava.util.*;Importcom.afy.app.action.*; Public  class simpleinterceptor extends abstractinterceptor{    //The name of the simple interceptor    PrivateString name;//Setter method for setting the name of the simple interceptor     Public void SetName(String name) { This. name = name; } PublicStringIntercept(Actioninvocation invocation)throwsexception{//Get an action instance that was interceptedLoginaction action = (loginaction) invocation.getaction ();//When the print execution startsSYSTEM.OUT.PRINTLN (name +"The action of the Interceptor---------"+"The time to start executing the login action is:"+NewDate ());//Get the time to start executing action        LongStart = System.currenttimemillis ();//Execute the last interceptor of the Interceptor        //If there are no other interceptors after the interceptor, the action's intercepted method is executed directlyString result = Invocation.invoke ();//The time when the print execution endedSYSTEM.OUT.PRINTLN (name +"The action of the Interceptor-------"+"The time to execute the login action is:"+NewDate ());LongEnd = System.currenttimemillis (); SYSTEM.OUT.PRINTLN (name +"The action of the Interceptor---------"+"The time that the action was executed is"+ (End-start) +"milliseconds");returnResult }}

Register the Interceptor defined in the previous step in Strutx.xml and reference the above-defined interceptor in the action you need to use.

<?xml version= "1.0" encoding= "GBK"?><! DOCTYPE struts Public "-//apache software foundation//dtd struts Configuration 2.3//en" "Http://struts.apache.org/dt Ds/struts-2.3.dtd "><struts>    <!--use constants to configure the character set used by the app--    <constant name="struts.i18n.encoding" value="GBK"/>     <!--Configure the package that the system uses--    < package name="Lee" extends= "struts-default">        <!--applications need to use interceptors configured under this element-        <interceptors>            <!--configuring Mysimple interceptors --            <Interceptor name= "mysimple"class=" Org.crazyit.app.interceptor.SimpleInterceptor ">                            <!--specify parameter values for the Interceptor--                <param name="name">Simple Interceptor</param>            </Interceptor>        </interceptors>        <action name= "Login" class=" Org.crazyit.app.action.LoginAction ">            <result name="error">/web-inf/content/error.jsp</result>            <result>/web-inf/content/welcome.jsp</result>             <!--Configure the system's default interceptor--            <interceptor-ref name="Defaultstack"/>            <!--apply a custom Mysimple interceptor--            <interceptor-ref name="Mysimple">                <param name="name">The Interceptor after renaming</param>            </interceptor-ref>        </Action>        <action name="*">            <result>/web-inf/content/{1}.jsp</result>        </Action>    </Package ></struts>


The implementation principle of interceptor

Most of the time, the Interceptor method is invoked in the form of proxies. The block implementation of Struts 2 is relatively straightforward. When the request arrives at the servletdispatcher of Struts 2, struts 2 looks for the configuration file, instantiates the relative interceptor object based on its configuration, and then strings it into a list, the last one to invoke the interceptor in the list.



The reason why we can use interceptors so flexibly is due to the use of dynamic agents. A dynamic agent is a proxy object that makes different processing based on the customer's needs. For the customer, just know a proxy object on the line. In that Struts2, how is the interceptor invoked through a dynamic proxy? When the action request arrives, an action proxy object is generated by the agent of the system, which invokes the action's execute () or the specified method, and finds the interceptor corresponding to the action in Struts.xml. If there is a corresponding interceptor, these interceptors are called before the action's method executes, and if there is no corresponding interceptor, the action method is executed. The system's call to the Interceptor is implemented by Actioninvocation.

the difference from the filter

Filters can be simply understood as "take what you want", ignoring things you don't want, and interceptors can simply be understood as "refusing what you want" and caring about what you want to reject, such as blocking sensitive words on a BBS forum.

1. Interceptors are based on the Java reflection mechanism, and filters are based on function callbacks.

2. The filter relies on the servlet container, and the interceptor does not depend on the servlet container.

3. The interceptor only works on the action, and the filter can work on almost all requests.

4. The interceptor can access the action context, the object in the value stack, and the filter cannot.

5. In the life cycle of an action, interceptors can be called multiple times, and filters can only be called once when the container is initialized.

Struts2 (vi) Interceptor mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.