Struts2 interceptor principle and example

Source: Internet
Author: User

Struts2 interceptor principle and example
Struts2 interceptor Definition 1. the Struts2 interceptor is a method used to access an Action or Action. It blocks fields before or after access, and the Struts2 interceptor is pluggable. The Interceptor is an implementation of AOP. 2. interceptor Stack ). The Struts2 interceptor stack connects the interceptor into a chain in a certain order. When accessing intercepted methods or fields, the interceptor in the Struts2 interceptor chain will be called in the order defined previously. II. Implementation of Struts2 interceptor principle the implementation of Struts 2 interceptor is relatively simple. When a request arrives at the ServletDispatcher of Struts2, Struts 2 searches for the configuration file, instantiates the relative interceptor object based on the configuration, and then Concatenates the object into a list ), finally, the interceptor in the list is called one by one. In fact, the reason why we can use the interceptor so flexibly is entirely due to the use of "dynamic proxy. Dynamic proxy is used to process proxy objects differently based on customer needs. For customers, you only need to know a proxy object. In Struts2, how is the interceptor called through a dynamic proxy? When an Action request arrives, the system proxy generates an Action proxy object, which calls the Action's execute () or specified method and. search for the interceptor corresponding to the Action in xml. If a corresponding interceptor exists, the interceptor is called before (after) The Action method is executed. If no corresponding interceptor exists, the Action method is executed. The system calls the interceptor through ActionInvocation. The Code is as follows: copy the Code if (interceptors. hasNext () {Interceptor interceptor = (Interceptor) interceptors. next (); resultCode = interceptor. intercept (this);} else {if (proxy. getConfig (). getMethodName () = null) {resultCode = getaction(cmd.exe cute ();} else {resultCode = invokeAction (getAction (), proxy. getConfig () ;}} copy code 3. the intercept method is the core method for implementing the entire Interceptor mechanism, except for the init and destory methods. The parameter ActionInvocation it depends on is the famous Action scheduler. Let's take a look at a typical abstract implementation class of Interceptor: copy the code public abstract class AroundInterceptor extends actinterceptor {/* (non-Javadoc) * @ see com. opensymphony. xwork2.interceptor. abstractInterceptor # intercept (com. opensymphony. xwork2.ActionInvocation) */@ Override public String intercept (ActionInvocation invocation) throws Exception {String result = null; before (invocation); // call the next Interceptor. If the interceptor does not exist, execute the Action result = Invocation. invoke (); after (invocation, result); return result;} public abstract void before (ActionInvocation invocation) throws Exception; public abstract void after (ActionInvocation invocation, String resultCode) throws Exception;} in this implementation class, the copied code has actually implemented the prototype of the simplest interceptor. It is worth noting that an important method is invocation. invoke (). This is the method in ActionInvocation, and ActionInvocation is the Action scheduler. Therefore, this method has the following two meanings: 1. if there are other Interceptor in the Interceptor stack, then invocation. invoke () will call the execution of the next Interceptor in the stack. 2. If the interceptor stack contains only Action, invocation. invoke () will call the Action for execution. Invocation. invoke () is the core of the entire interceptor framework. Based on this implementation mechanism, we can also get the following two very important inferences: 1. if invocation is not used in the interceptor. invoke () is used to call the next element in the stack. Instead, a string is directly returned as the execution result, and the entire execution is aborted. 2. we can use invocation. invoke () is the boundary. The code in the interceptor is divided into two parts, in invocation. the code before invoke () will be executed in sequence before the Action, while the code before invocation. the code after invoke () will be executed in reverse order after the Action. Therefore, we can use invocation. invoke () as the true interception point of the Action code to implement AOP. 3. parse the source code to see how Struts2 ensures the execution sequence between the interceptor, Action, and Result. Previously, I mentioned that ActionInvocation is the scheduler in Struts2. In fact, the scheduling and execution of these codes are completed in the implementation class of ActionInvocation. Here, I extracted the invoke () method from defaactionactioninvocation, which will show us everything. Copy the public String invoke () throws Exception {String profileKey = "invoke:"; try {UtilTimerStack. push (profileKey); if (executed) {throw new IllegalStateException ("Action has already executed");} // call the interceptor code in the interceptor stack to execute if (interceptors. hasNext () {final InterceptorMapping interceptor = (InterceptorMapping) interceptors. next (); UtilTimerStack. profile ("interceptor:" + interceptor. getName (), new Uti LTimerStack. profilingBlock <String> () {public String doProfiling () throws Exception {// use ActionInvocation as a parameter and call the intercept method in interceptor to execute resultCode = interceptor. getInterceptor (). intercept (defaactionactioninvocation. this); return null ;}}) ;}else {resultCode = invokeActionOnly () ;}// this is needed because the result will be executed, then control will return to the Interceptor, which will // Return above and flow through again if (! Executed) {// execute PreResultListener if (preResultListeners! = Null) {for (Iterator iterator = preResultListeners. iterator (); iterator. hasNext ();) {PreResultListener listener = (PreResultListener) iterator. next (); String _ profileKey = "preResultListener:"; try {UtilTimerStack. push (_ profileKey); listener. beforeResult (this, resultCode);} finally {UtilTimerStack. pop (_ profileKey) ;}}// now execute the result, if we're supposed to // action and interceptor are completed, Execute Result if (proxy. getExecuteResult () {executeResult ();} executed = true;} return resultCode;} finally {UtilTimerStack. pop (profileKey) ;}} copy the code. From the source code, we can see four different layers of the Action layer, which are reflected in this method. They are: Interceptor), Action, PreResultListener, and Result. This method ensures the orderly calling and execution of these layers. As a result, we can also see that Struts2 has many considerations in the Action hierarchy design. Each layer has a high degree of scalability and insertion points, this allows programmers to add their own implementation mechanisms at any level they like to change Action behavior. Here, we need to emphasize the execution call of the interceptor part: resultCode = interceptor. getInterceptor (). intercept (defaactionactioninvocation. this); originally, the intercept () method recursively calls the invoke () method of ActionInvocation, And the ActionInvocation loop is nested in intercept () until the statement result = invocation. invoke () Execution ends. In this way, Interceptor will end the execution in reverse order according to the initial execution. An ordered linked list is converted into a stack execution process through recursive calls. The Code executed in an ordered sequence is converted into a code process in which two segments are executed in the opposite order, thus cleverly Implementing AOP. This has become the AOP basis for the Action layer of Struts2. There are many similarities between the interceptor and the filter, but there are fundamental differences between the two. The main differences are as follows: 1) the interceptor is based on the JAVA reflection mechanism, while the filter is based on function callback. 2) The filter depends on the Servlet container, and the interceptor does not rely on the Servlet container. 3) the interceptor can only work on Action requests, while the filter can work on almost all requests. 4) the interceptor can access objects in the Action context and value stack, but the filter cannot. 5) in the Action lifecycle, the interceptor can be called multiple times, the filter can only be called once during container initialization.

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.