How Struts2 Interceptor Works
Interceptors execute around the execution of Action and Result. The Struts2 interceptor works as shown in Figure 10.2. As can be seen from the above figure, the implementation principle of Struts2 interceptor is similar to that of Servlet Filter, which intercepts the method to be executed (execute() by chain execution. First execute the interceptor configured by Action, and execute the interceptor in Action and After the Result is executed, the interceptor is executed again (in the reverse order of the previous call). During the execution of this chain, any interceptor can return directly, thereby terminating the execution of the remaining interceptors, Action and Result.
When the mock() method of Actioninvocation is called, it starts to execute the first interceptor of Action configuration. After the interceptor makes corresponding processing, it will call the invoke() method of Actioninvocation again. The Actioninvocation object is responsible for tracking the state of the execution process and controlling the The right to the appropriate interceptor. Actioninvocation transfers control to the interceptor by calling the Intercept() method of the interceptor. Therefore, the execution process of the interceptor can be regarded as a recursive process, and subsequent interceptors continue to execute until the last one Interceptor, invoke() method will execute Action.
The interceptor has a three-stage, conditional execution cycle as follows:
(1) Do some preprocessing before the Action is executed. Interceptors can prepare, filter, change or manipulate any accessible data, including Actions.
(2) Call the evoke() method of Actioninvocation to transfer control to the subsequent interceptor or return the result string to terminate the execution. If the interceptor decides that the processing of the request should not continue, it may not call the invoke() method, but directly return a control string. In this way, subsequent executions can be stopped and it is decided which result to present to the client.
(3) Do some processing after the Action is executed. At this point, the interceptor can still change the objects and data that can be accessed, but the framework has already selected a result to present to the client.
Example of custom interceptor:
(1) Custom interceptor class
1 package cn.test.interceptor; 2 3 import com.opensymphony.xwork2.ActionInvocation; 4 import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 5 6 public class MyTimeIntercepter extends AbstractInterceptor { 7 8 private static final long serialVersionUID = 1L; 9 10 @Override 11 public String intercept(ActionInvocation invocation) throws Exception { 12 //1. Execute the work before the Action: Get the start execution time 13 long startTime = System.currentTimeMillis(); 14 System.out.println("Execute the work before the Action, start time: " + startTime); 15 // 2. Execute Subsequent interceptor or Action 16 String result = invocation.invoke(); 17 // 1. Work after executing Action: Calculate and output execution time 18 long endTime = System.currentTimeMillis(); 19 20 System.out.println(" Execute the work after Action, end time: " + endTime); 21 System.out.println("Total time: " + (endTime - startTime)); 22 return result; 23 } 24 25 }
After obtaining the result string, the My Timer Interceptor interceptor records the execution time and outputs it on the console. At this point the interceptor can do something with the result string, but it cannot stop or change the response here. For the
My Timer Interceptor interceptor, it doesn't care about the result, so it doesn't look at the returned result string.
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <struts> 6 <package name="default" namespace="/" extends="struts-default"> 7 <!-- 配置默认的行为 --> 8 <default-action-ref name="defaultAction"></default-action-ref> 9 <!-- 配置默认action --> 10 <action name="defaultAction"> 11 <result type="redirect">/error.jsp</result> 12 </action> 13 </ package > 14 15 <!-- Interceptor Configuration--> 16 < package name="intercepter" namespace="/ " extends ="struts-default"> 17 <!-- Interceptor sub-elements are used in interceptors to define interceptors --> 18 <interceptors> 19 <!-- interceptor element name attribute: the name of the interceptor, class : custom Fully qualified class name of the interceptor class --> 20 <interceptor name="myTime" class ="cn.test.interceptor. MyTimeIntercepter"></interceptor> 21 <interceptor-stack name="myTimeStack"> 22 <interceptor-ref name="myTime"></interceptor-ref> <!-- set the custom interceptor to the top of the stack --> 23 <interceptor-ref name="defaultStack"></interceptor-ref> <!--Call struts default interceptor--> 24 </interceptor-stack> 25 </interceptors> 26 27 <!--Browser input http: // localhost:8080/strutsstu4/index and access it will trigger the execution of the interceptor and calculate the execution time of the interceptor--> 28 <action name="index"> 29 <result >/index.jsp</result> 30 < interceptor-ref name="myTimeStack"></interceptor-ref> <!-- Let the interceptor stack myTimeStack intercept --> 31 </action> 32 </package> 33 34 </struts>
(3) View page:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>My JSP 'index.jsp' starting page</title> 7 </head> 8 9 <body> 10 This is index page. <br> 11 </body> 12 </html>
error.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>My JSP 'success.jsp' starting page</title> 6 </head> 7 8 <body> 9 This is error page. <br> 10 </body> 11 </html>
(4) Deploy and test
The browser enters http://localhost:8080/strutsstu4/index and accesses it, it will trigger the execution of the interceptor, the console prints the execution time of the interceptor, and the page jumps to index.jsp, as follows:
If you visit a URL that does not have a corresponding action, such as http://localhost:8080/strutsstu4/sss, the default action is executed, and the 404 error page is replaced.