1. Interceptor introduction
The function of the interceptor is similar to the Filter in the web.xml file. It can intercept user requests and control the page by intercepting user requests. The interceptor is configured in Struts-core-2.2.3.jar. The original interceptor is configured in struts-default.xml, which seals the basic usage method of the interceptor.
The Struts2 interceptor function is similar to a Servlet filter. Before Action executes the execute method, Struts2 will first execute the interceptor referenced in struts.xml. If there are multiple interceptors, it will be executed in order of up and down. After executing the interceptor method of all interceptors, the execution method of Action will be executed.
The Struts2 interceptor must implement this interface from com.opensymphoy.xwork2.interceptor.Interceptor. The following three methods need to be implemented in the defined interceptor:
void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception;
Custom interceptors need to override the above three methods. In addition, the interceptor configuration file struts.xml of Struts2 inherits the original file struts-default.xml file, so that all the configuration information in struts-default.xml will be automatically owned in the corresponding <package>. The specific code is as follows:
<package name="demo" extends="struts-default" > ... </package>
2. Add an interceptor
To use an interceptor, you must be configured. Struts2 uses the mapping method, so if you want to use a certain function, you must be configured in the configuration file, and the interceptor is no exception. Therefore, the corresponding interceptor element must be added in the package, and the interceptor must be associated with the corresponding class file, so that the corresponding interceptor will be executed before the action is executed. The specific usage method is as follows.
(1) Add the configuration file struts.xml and add an interceptor to the file
<package name="testLogin" namespace="/" extends="struts-default"> <!-- Interceptor--> <interceptor name="myInterceptor"></interceptor> </interceptor> <action name="demo"> <result name="error" type="redirect">/error.jsp</result> <result name="success">/success.jsp</result> <result name="checkError">/checkSession.jsp</result> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package>
In the package above, an interceptor named myInterceptor was added, and a java class was registered for the interceptor, which was named MyInterceptor and was blocked in the com.interceptor package. In addition, a corresponding action has been added to the package. Before executing the action, the myInterceptor interceptor will be executed first.
(2) Write the registered interceptor class MyInterceptor. This class must implement the com.opensymphoy.xwork2.interceptor.Interceptor interface and override the corresponding method
package com.interceptor; import java.util.Map; import com.entity.User; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; public class MyInterceptor implements Interceptor{ private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public void destroy() { // TODO Auto-generated method stub System.out.println("----destroy()----"); } @Override public void init() { // TODO Auto-generated method stub System.out.println("------Init()-------"); } @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("-----------"); Map<String, Object> session= invocation.getInvocationContext().getSession(); if(session.get("username")!=null){ System.out.println("Login successfully!"); //session.put("username",user.getUsername()); return invocation.invoke(); }else{ System.out.println("Login failed! "); return "checkError"; } } }(3) After the first two steps, the interceptor has been configured. The last part is to use the interceptor. Add the corresponding tag to the display page, and specify the action named demo created above for the tag. Then execute the page to print out the corresponding interceptor content in the console.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="demo"> Username: <input type="text" name="username"><br> Password: <input type="text" name="password"><br> <input type="submit" name="ok" value="submit"> </form> </body> </html>
Printout content:
Analyze the output results. In the program compilation stage, the configuration file struts.xml will first read the configuration file struts.xml, and in the configuration file action, search for whether the interceptor has been added. If an interceptor is added, find whether the interceptor or the interceptor stack is defined in <interceptors> according to the interceptor name. If it is found that the interceptor is defined, find the corresponding registered class based on the interceptor, and finally find the registered class in the package and execute the corresponding init() method. The general process of the program running stage is similar to the compilation stage. After the user submits a request in the foreground, he will look for the corresponding action in struts.xml. If it is found, the interceptor will be found. If it is not found, the corresponding error will be thrown. Finally, the intercept method of the interceptor registration class is executed.
3. Interceptor stack
Interceptors also have the concept of stack. They define the used interceptors to a shared state to achieve unified management, so that interceptors can be shared in the package, greatly facilitating the use of interceptors. Repeated interceptors are often used in a package. If you add interceptor-ref to the Action every time, it will be very troublesome. Then the interceptor stack is generated to solve this problem. The specific configuration is as follows:
<package name="testLogin" namespace="/" extends="struts-default"> <!-- Interceptor--> <interceptor name="myInterceptor"></interceptor> <!-- Define a public interceptor chain. In the action tag, only the interceptor chain needs to be referenced --> <interceptor-stack name="defaulttstack1"> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="demo"> <result name="error" type="redirect">/error.jsp</result> <result name="success">/success.jsp</result> <result name="checkError">/checkSession.jsp</result> <interceptor-ref name="defaultstack1"></interceptor-ref> </action> </package>
In the example, interceptor-stack is used to define an interceptor stack named defaulttstack1. The interceptor to be executed is added to the stack, the interceptor is encapsulated, and the interceptor stack is called directly in the Action, realizing the sharing of the interceptor stack.
4. Default interceptor stack
In addition, the default interceptor stack can be defined, that is, if no interceptor is defined in an Action, it will execute the public interceptor by default. It belongs to the same level as the interceptors tag and is defined using default-interceptor-ref.
<package name="testLogin" namespace="/" extends="struts-default"> <!-- Interceptor--> <interceptor name="myInterceptor"></interceptor> <!-- Define a public interceptor chain. In the action tag, only the interceptor chain needs to be referenced --> <interceptor-stack name="defaultinter"> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- Define the default interceptor stack and will be automatically registered in the action --> <default-interceptor-ref name="defaultinter"></default-interceptor-ref> <action name="demo"> <result name="error" type="redirect">/error.jsp</result> <result name="success">/success.jsp</result> <result name="checkError">/checkSession.jsp</result> </package>
The defined default interceptor stack only executes the custom default interceptor stack if the Action does not specify an interceptor. If the Interceptor is redefined in the Action, it will override the custom default interceptor stack.
5. No interceptor execution
There is another situation where a package defines the default interceptor, but no interceptor is required to be executed in a certain action written. Then, you can add an interceptor named defaultStack to the corresponding action. It is the system's default interceptor and there will be no operations.
<package name="testLogin" namespace="/" extends="struts-default"> <!-- Interceptor--> <interceptor name="myInterceptor"></interceptor> <!-- Define a public interceptor chain. In the action tag, only the interceptor chain needs to be referenced --> <interceptor-stack name="defaultinter"> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- Define the default interceptor stack and will be automatically registered in the action --> <default-interceptor-ref name="defaultinter"></default-interceptor-ref> <action name="demo"> <result name="error" type="redirect">/error.jsp</result> <result name="success">/success.jsp</result> <result name="checkError">/checkSession.jsp</result> <!-- Add defaultStack to ensure that the interceptor is not executed--> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package>
6. Intercept method
6.1 Usage
The above interceptor only implements the interceptor intercepting Action. In fact, the interceptor has a very powerful function and can also intercept the corresponding Action method. The difference between intercepting Action is that if you want to intercept the method, you must inherit the class MethodFilterInterceptor. This class is enclosed in xwork-core.jar, which once again proves that WebWork is the core of Struts2. In addition, it is also necessary to add corresponding attributes to the configuration file to determine the interception method and the non-interception method. The specific configuration method is as follows:
<package name="testLogin" namespace="/" extends="struts-default"> <!-- Interceptor--> <interceptor name="myInterceptor"></interceptor> <!-- Define a public interceptor chain. In the action tag, only the interceptor chain needs to be referenced --> <interceptor-stack name="defaultinter"> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="demo"> <result name="error" type="redirect">/error.jsp</result> <result name="success">/success.jsp</result> <result name="checkError">/checkSession.jsp</result> <result name="checkError">/checkSession.jsp</result> <!-- Configure the intercepting method in the defaultStack, add the intercepted method name in the parameter includeMethods, and add the name that does not need to be intercepted in the excludeMethods--> <interceptor-ref name="defaultStack"> <param name="includeMethods"> Add the method name to be intercepted</param><!-- Intercepting method--> <param name="excludeMethods">Add the method name that does not require interception</param><!-- Non-intercept method--> </interceptor-ref> </action> </package>
Code in the class that inherits the corresponding interceptor method of the MethodFilterInterceptor class:
package com.interceptor; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Interceptor.MethodFilterInterceptor; public class inter extends MethodFilterInterceptor { @Override public String doIntercept(ActionInvocation invocation) throws Exception { System.out.println("--intercept()--"); //Get the corresponding Session Map<String,Object> session=invocation.getInvocationContext().getSession(); Map request=(Map)ActionContext.getContext().get("request"); String username=(String)request.get("user.username"); if(session.get("username") != null){ String result=invocation.invoke(); System.out.println("--end()--"); return result; } } } } 6.2 Demo
Let’s look at an example of an interception method and analyze the results. The following example demonstrates the output results of the intercept method. In the instance, a loginAction class is created separately to add the method to be executed by Action; the Inter class is overridden in the interceptor method, and outputs whether to intercept a certain method in the console; the login.jsp file is added to demonstrate the execution of the three methods respectively.
(1) The definition of the method interceptor in struts.xml defines an interceptor named inter in the package, and specifies parameters in the interceptor. includeMethods is used to intercept Method1. Method2 in excludeMethods means that the Methods2 method is not intercepted. The specific configuration is as follows:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.action.extension" value=","></constant> <package name="login" extends="struts-default"> <interceptor name="inter"> <param name="includeMethods">Method1</param> <!-- Intercept Method1 method --> <param name="excludeMethods">Method2</param> </interceptor> <interceptor-stack name="myInterceptor"> <interceptor-ref name="inter"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptor-stack> </interceptors> <action name="loginaction"> <result name="success">success.jsp</result> <result name="error">error.jsp</result> <result name="error">error.jsp</result> <result name="cancel" type="redirectAction">Welcome</result> <interceptor-ref name="inter"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package> </struts>
(2) LoginAction class, configure the action in login.jsp, and add three methods Method1-Method3 to this class, respectively, Method1 is intercepted, Method2 and Method3 are not intercepted, and finally we check the output result.
package com.action; import com.opensymphony.xwork2.ActionSupport; public class loginAction extends ActionSupport { @Override public String execute() throws Exception { if(this.username.equals("admin") && this.password.equals("admin")){ return "success"; }else if(this.username.equals("cancel") && this.password.equals("cancel")){ return "cancel"; }else{ return "error"; } } public void Method1(){ System.out.println("Execution method: Method1"); } public void Method2(){ System.out.println("Execution method: Method2"); } public void Method3(){ System.out.println("Execution method: Method3"); } private String username; private String password; public String getUsername(){ return this.username; } public void setUsername(String username){ this.username=username; } public String getPassword(){ return this.password; } public void setPassword(String password){ this.password=password; } }(3) Inter class, inheriting the MethodFilterInterceptor class, and is used to implement intercepting methods. Rewrite the doIntercept method and add the corresponding information for intercept to the method.
package com.interceptor; import java.util.Date; import java.util.Map; import com.action.loginAction; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Interceptor.MethodFilterInterceptor; public class inter extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("Interceptor intercepts before Action execution"+new Date()); String result=invocation.invoke(); //Execute the Action method System.out.println("Interceptor intercepts after Action execution"+new Date()); return result; } }(4) login.jsp, add three buttons on the jsp page, demonstrate three methods respectively, and judge the interceptor's interception of the method. The actions posted back by the three buttons after clicking are dynamically added in JavaScript. This achieves the method of executing different actions in a form. Of course, there are other methods, which will be discussed in the next article.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> //Method 1, define an instance of the intercepted method function method1(){ var form=document.forms[0]; form.action="loginaction!Method1"; form.submit(); } //Method 2, add a method that does not intercept for button 2 function method2(){ var form=document.forms[0]; form.action="loginaction!Method2"; form.submit(); } //Method 3, add a method that does not intercept for button 3 function method3(){ var form=document.forms[0]; form.action="loginaction!Method3"; form.submit(); } </script> </head> <body> <form> Username: <input type="text" name="username"><br> Password: <input type="text" name="password"><br> <input type="submit" name="ok" value="button1" onclick="method1()"> <input type="submit" name="ok1" value="button2" onclick="method2()"> <input type="submit" name="ok2" value="button3" onclick="method3()"> </form> </body> </html> Page view after the run is completed:
(5) Analyze the running results, click buttons 1, 2, and 3 respectively, and output the results in the console. Button 1 is the bound method1. This method intercepts in struts.xml. If the result is correct, the intercepted result will be displayed. The corresponding buttons 2 and 3 only output the running results because they are not intercepted. Then look at the result diagram below:
The result diagram is exactly the result of our analysis. Button 1 was intercepted, and the doIntercept method in the inter class was executed. The corresponding buttons 2 and 3 of the two were not intercepted. In other words, Method1 is placed in the whitelist of the method interceptor, and the method must be intercepted when executed; Method2 is placed in the blacklist of the interceptor, and there is no need to intercept the method; Method3 does not do anything.
7. Conclusion
The content of the interceptor is summarized here. The interceptor provides very powerful functions, allowing developers to control the output results at runtime, increasing programming flexibility. In addition, don’t try to remember any theoretical things. You must analyze them rationally, practice more, and make a few examples to have a deeper understanding of the analysis results.
PS: Functional description of the interceptor provided by Struts2 (XWork)
Interceptor | name | illustrate |
Alias Interceptor | alias | The request parameters are converted to different name files between different requests, and the request content remains unchanged |
Chaining Interceptor | chain | Let the properties of the previous Action be accessed by the next Action, and are now used in conjunction with the result of the chain type (<result type="chain">). |
Checkbox Interceptor | checkbox | Added checkbox automatic processing code, setting the content of uncheckbox to false, while html does not submit uncheckbox by default. |
Cookies Interceptor | Cookies | Use the configured name and value to refer to cookies |
Conversion Error Interceptor | conversionError | Adds an error from the ActionContext to the Action's property field. |
Create Session Interceptor | createSession | Automatically create HttpSession to use for interceptor services that require HttpSession. |
Debugging Interceptor | debugging | Provide different debugging pages to show the internal data status. |
Execute and Wait Interceptor | execAndWait | Execute Action in the background while taking the user to an intermediate waiting page. |
Exception Interceptor | Exception | Position the exception to a screen |
File Upload Interceptor | fileUpload | Provide file upload function |
I18n Interceptor | i18n | Record the locale selected by the user |
Logger Interceptor | logger | Output Action's name |
Message Store Interceptor | store | Store or access messages, errors, field errors, etc. that appear in Action classes that implement ValidationAware interface. |
Model Driven Interceptor | model-driven | If a class implements ModelDriven, place the result obtained by getModel in the Value Stack. |
Scoped Model Driven | scoped-model-driven | If an Action implements ScopedModelDriven, the interceptor will take out the model from the corresponding Scope and call the Action's setModel method and put it inside the Action. |
Parameters Interceptor | params | Set the parameters in the request to the Action. |
Prepare Interceptor | prepare prepare | If Acton implements Preparable, the interceptor calls the prepare method of the Action class. |
Scope Interceptor | scope | Easy way to save Action state into session and application. |
Servlet Config Interceptor | servletConfig | Provides methods to access HttpServletRequest and HttpServletResponse, accessing in the form of a Map. |
Static Parameters Interceptor | staticParams | Set the contents in <param> in <action> into the corresponding Action from the struts.xml file. |
Roles Interceptor | roles | Determines whether the user has a JAAS specified Role, otherwise it will not be executed. |
Timer Interceptor | timer | Output Action execution time |
Token Interceptor | token | Avoid double-clicking through token |
Token Session Interceptor | tokenSession | Like Token Interceptor, however, when double-clicking, the requested data is stored in the Session |
Validation Interceptor | Validation | Verify submitted data using the content defined in the action-validation.xml file. |
Workflow Interceptor | workflow | Call Action's validate method, and once there is an error, it will be relocated to the INPUT screen. |
Parameter Filter Interceptor | N/A | Remove unnecessary parameters from the parameter list |
Profiling Interceptor | Profiling | Activate profile via parameters |