Part 15th _struts2.1 Interceptor Depth analysis, exception handling

Source: Internet
Author: User
Tags xslt

RecoveryInterceptor: Interceptor.

While we declare the interceptor (the default interceptor will not work at this time), we must add the default interceptor provided by STRUTS2 (otherwise the return information of the access page may surprise you, such as a bunch of messy information about the submitted form information), And we declare that the interceptor must be before the default.

Steps to use interceptors:

    1. Define the appropriate interceptor class, implement Interceptor or inherit Abstractinterceptor (the abstract class NULL implementation implements the INIT and destroy methods of the Interceptor interface)
    2. Declare the Interceptor in Struts.xml, configure it in the relevant action, and finally remember to add the default interceptor

Below we use interceptors to help us read the parameters in the XML (analogy with the previous use of filters to implement blacklist forbidden message example, here does not need to use the GetParameter method can be easily read parameter values).

Here's an example:

Create a new Com.test.interceptor package, and create a new class Myinterceptor under the package:

Package Com.test.interceptor;import Com.opensymphony.xwork2.actioninvocation;import Com.opensymphony.xwork2.interceptor.interceptor;import Com.opensymphony.xwork2.interceptor.PreResultListener; public class Myinterceptor implements interceptor{private string Hello;//Receive Interceptor value in the Hello property in Struts.xml configuration public String Gethello () {return Hello;} public void Sethello (String hello) {This.hello = hello;} public void Destroy () {System.out.println ("destroy invoked");} public void init () {System.out.println ("init invoked"); System.out.println ("Hello:" + hello);} Public String intercept (actioninvocation invocation) throws Exception{system.out.println ("intercept invoked"); String result = Invocation.invoke (); SYSTEM.OUT.PRINTLN (result); return result;}}

To get a clearer picture of how interceptors work, we write several interceptors, MyInterceptor2:

Package Com.test.interceptor;import Com.opensymphony.xwork2.actioninvocation;import Com.opensymphony.xwork2.interceptor.abstractinterceptor;public class MyInterceptor2 extends abstractinterceptor{@ Overridepublic String Intercept (actioninvocation invocation) throws Exception{system.out.println ("MyInterceptor2 Invoked "); String result = Invocation.invoke (); System.out.println ("RESULT2:" + result); return result;}}

One more MyInterceptor3 (the first class-based interceptor, which is based on the method):

Package Com.test.interceptor;import Com.opensymphony.xwork2.actioninvocation;import Com.opensymphony.xwork2.interceptor.methodfilterinterceptor;public class MyInterceptor3 extends methodfilterinterceptor{@Overrideprotected String dointercept (actioninvocation invocation) throws exception{ System.out.println ("MyInterceptor3 invoked"); String result = Invocation.invoke (); System.out.println ("RESULT3:" + result); return result;}}

It is then configured on the basis of the original struts.xml:

<?xml version= "1.0" encoding= "UTF-8"? ><! DOCTYPE struts Public "-//apache software foundation//dtd struts Configuration 2.0//en" "Http://struts.apache.org/dt Ds/struts-2.0.dtd "><struts><package name=" struts2 "extends=" Struts-default "><interceptors> <interceptor name= "Myinterceptor" class= "Com.test.interceptor.MyInterceptor" ><param name= "Hello" > World</param></interceptor><interceptor name= "MyInterceptor2" class= " Com.test.interceptor.MyInterceptor2 "></interceptor><interceptor name=" MyInterceptor3 "class=" Com.test.interceptor.MyInterceptor3 "></interceptor></interceptors> <action name=" register "cl ass= "Com.test.action.RegisterAction" ><result name= "Success" >/success.jsp</result><result name= "Input" >/register.jsp</result><interceptor-ref name= "Myinterceptor" ></interceptor-ref>< Interceptor-ref name= "MyInterceptor2" ></interceptor-ref> <inteRceptor-ref name= "MyInterceptor3" ></interceptor-ref></action></package></struts> 

Information about us that will be output during server startup (part of the interception):

Info: Parsing configuration file [Struts-plugin.xml]
2015-7-23 9:21:28 Com.opensymphony.xwork2.util.logging.commons.CommonsLogger Info
Info: Parsing configuration file [Struts.xml]
Init invoked
Hello:world
2015-7-23 9:21:30 Org.apache.catalina.startup.HostConfig Deploydescriptor
Info: Deploying Configuration Descriptor Host-manager.xml
2015-7-23 9:21:30 Org.apache.catalina.startup.HostConfig Deploydescriptor
Info: Deploying Configuration Descriptor Manager.xml

To access http://localhost:8080/struts2/register.action, the console output is as follows when successfully transferring to the results page:

Intercept invoked
MyInterceptor2 invoked
MyInterceptor3 invoked
validate~~~~~~~~~~~~~~~~
Execute invoked
Result3:success
Result2:success
Success

Here validate~~~~~~~~~~~~~~ get output is because we in the Registeraction validate method to print the change of the line, from the output we can peek at the interceptor execution time and execution process, it and the filter operation mechanism is basically consistent.

As we wrote in the previous MyInterceptor3, it's a method-based interceptor, how do I get it into effect? That is to add additional parameters to the configuration when it is configured:

<interceptor-ref name= "MyInterceptor3" ><param name= "Excludemethods" >execute</param></ Interceptor-ref>

In this way, the page is accessed, and the output becomes like this:

Intercept invoked
MyInterceptor2 invoked
validate~~~~~~~~~~~~~~~~
Execute invoked
Result2:success
Success

In this way, we have banned the third interceptor from the Execute method.

Also, do you think that when the interceptor is a lot of time, an action to configure multiple interceptors some trouble? We think of this problem, Struts2 designers have long thought, the solution can be in the struts-default.xml to get some enlightenment:

The method is to use the interceptor stack:

<interceptors><interceptor name= "Myinterceptor" class= "Com.test.interceptor.MyInterceptor" ><param Name= "Hello" >world</param></interceptor><interceptor name= "MyInterceptor2" class= " Com.test.interceptor.MyInterceptor2 "></interceptor><interceptor name=" MyInterceptor3 "class=" Com.test.interceptor.MyInterceptor3 "></interceptor><interceptor-stack name=" Mystack ">< Interceptor-ref name= "Myinterceptor" ></interceptor-ref><interceptor-ref name= "MyInterceptor2" > </interceptor-ref><interceptor-ref name= "Defaultstack" ></interceptor-ref></ Interceptor-stack></interceptors>

So in action we just have to introduce Mystack,myinterceptor and MyInterceptor2 and Defaultstack will all work.

In addition, if we do this in Struts.xml:

<interceptors><interceptor name= "Myinterceptor" class= "Com.test.interceptor.MyInterceptor" ><param Name= "Hello" >world</param></interceptor><interceptor name= "MyInterceptor2" class= " Com.test.interceptor.MyInterceptor2 "></interceptor><interceptor name=" MyInterceptor3 "class=" Com.test.interceptor.MyInterceptor3 "></interceptor><interceptor-stack name=" Mystack ">< Interceptor-ref name= "Myinterceptor" ></interceptor-ref><interceptor-ref name= "MyInterceptor2" > </interceptor-ref><interceptor-ref name= "Defaultstack" ></interceptor-ref></ Interceptor-stack></interceptors><default-interceptor-ref name= "Mystack" ></ Default-interceptor-ref>

That is, add a default interceptor to it so that all actions are referenced to this default interceptor.

One application scenario:

The most important use of interceptors is to verify the permissions: Define an interceptor to intercept the user's request, if the user is not logged in, we let the user log in, do not let him go back, if the user logged in, directly let the user into the corresponding main interface.

Struts provides us with one: global results (Global-results), shared by all action.

Struts2 By default using request forwarding, we can change its behavior by using the Redirect method. Type= "Redirect", how do we know if there is such a type, go back to Struts-default.xml (below to intercept some of our related parts):

<package name= "Struts-default" abstract= "true" > <result-types> <result-type name= "Chain" class= "Com.opensymphony.xwork2.ActionChainResult"/> <result-type name= "Dispatcher" class= "Org.apache.stru Ts2.dispatcher.ServletDispatcherResult "default=" true "/> <result-type name=" Freemarker "class=" Org.apache . Struts2.views.freemarker.FreemarkerResult "/> <result-type name=" Httpheader "class=" Org.apache.struts2.di Spatcher. Httpheaderresult "/> <result-type name=" redirect "class=" Org.apache.struts2.dispatcher.ServletRedirectResu LT "/> <result-type name=" redirectaction "class=" Org.apache.struts2.dispatcher.ServletActionRedirectResult "/> <result-type name=" stream "class=" Org.apache.struts2.dispatcher.StreamResult "/> <res Ult-type name= "Velocity" class= "Org.apache.struts2.dispatcher.VelocityResult"/> <result-type name= "XSLT" Class= "Org.apacHe.struts2.views.xslt.XSLTResult "/> <result-type name=" plaintext "class=" org.apache.struts2.dispatcher.Pl Aintextresult "/> </result-types>

You can see that the default is request forwarding dispatcher. Here is our program Authinterceptor:

Package Com.test.interceptor;import Java.util.map;import Com.opensymphony.xwork2.action;import Com.opensymphony.xwork2.actioninvocation;import Com.opensymphony.xwork2.interceptor.abstractinterceptor;public Class Authinterceptor extends abstractinterceptor{@Overridepublic String intercept (actioninvocation invocation) Throws exception{//usually we check whether the user is logged in, is through the session to complete the//Note that the session is not httpsession, it is struts2 encapsulated map, very good implementation of the hidden, in addition, It is easy to test with the unit test framework without resorting to the container map map = Invocation.getinvocationcontext (). getsession (); if (null = = Map.get ("user"))//user not logged in { return action.login; Return to login Interface}else{return Invocation.invoke ();}}}

Next is the related configuration in Structs.xml:

<?xml version= "1.0" encoding= "UTF-8"? ><! DOCTYPE struts Public "-//apache software foundation//dtd struts Configuration 2.0//en" "Http://struts.apache.org/dt Ds/struts-2.0.dtd "><struts><package name=" struts2 "extends=" Struts-default "><interceptors> <interceptor name= "Myinterceptor" class= "Com.test.interceptor.MyInterceptor" ><param name= "Hello" > World</param></interceptor><interceptor name= "MyInterceptor2" class= " Com.test.interceptor.MyInterceptor2 "></interceptor><interceptor name=" MyInterceptor3 "class=" Com.test.interceptor.MyInterceptor3 "></interceptor><interceptor name=" Authinterceptor "class=" Com.test.interceptor.AuthInterceptor "></interceptor><interceptor-stack name=" Mystack ">< Interceptor-ref name= "Authinterceptor" ></interceptor-ref><interceptor-ref name= "MyInterceptor" > </interceptor-ref><interceptor-ref name= "MyInterceptor2" ></interceptor-ref><iNterceptor-ref name= "Defaultstack" ></interceptor-ref></interceptor-stack></interceptors> <global-results><result name= "Login" type= "redirect" >/login.jsp</result></global-results ><action name= "register" class= "com.test.action.RegisterAction" ><result name= "Success" >/ Success.jsp</result><result name= "Input" >/register.jsp</result><!--<interceptor-ref Name = "Myinterceptor" ></interceptor-ref><interceptor-ref name= "MyInterceptor2" ></interceptor-ref >--><interceptor-ref name= "Mystack" ></interceptor-ref></action></package></ Struts>

Access http://localhost:8080/struts2/register.jsp, request forwarding the way the login address bar displays http://localhost:8080/struts2/ Register.action, redirected display http://localhost:8080/struts2/login.jsp;

Extensions-prevent forms from repeating commits: there are generally two ways

    • Use redirection.
    • Use tokens (tokens).

Add: Exception handling mechanism

We also take login.jsp as an example:

<body>  <form action= "login.action" >    username: <input type= "text" name= "username" size= "20"/ ><br>    Password: <input type= "password" name= "password" size= "/><br/> <input"        type = "Submit" value= "Submit" >    </form>  </body>

First set up two classes of usernameexception under the Com.test.exception package:

Package Com.test.exception;public class Usernameexception extends Exception{private string Message;public string GetMessage () {return message;} public void Setmessage (String message) {this.message = message;} Public usernameexception (String message) {super (message); this.message = message;}}

There is also a passwordexception:

Package Com.test.exception;public class Passwordexception extends Exception{private string Message;public string GetMessage () {return message;} public void Setmessage (String message) {this.message = message;} Public passwordexception (String message) {super (message); this.message = message;}}

In Loginaction, we assume that the user name is not "Hello" to throw an exception, the password is not "world" also throws an exception:

Package Com.test.action;import Com.opensymphony.xwork2.actionsupport;import com.test.exception.PasswordException; Import Com.test.exception.usernameexception;public class Loginaction extends actionsupport{private String username; private string Password;public string GetUserName () {return username;} public void Setusername (String username) {this.username = username;} Public String GetPassword () {return password;} public void SetPassword (String password) {this.password = password;} Public String Execute () throws Exception{if (! " Hello ". Equals (username)) {throw new Usernameexception (" username invalid ");} else if (! " World ". Equals (password)) {throw new passwordexception (" Password Invalid ");} Else{return SUCCESS;}}}

Do here, access to the login page, enter a non-"hello" user name, a lot of exception information is thrown to the user, which is obviously unfriendly, so we deal with this, so that the user name is illegal when prompted username invalid:

Nested tags under the Struts tab in Struts.xml:

<global-results><result name= "Login" type= "redirect" >/login.jsp</result><result Name= " Usernameinvalid ">/usernameinvalid.jsp</result></global-results><global-exception-mappings ><exception-mapping result= "" exception= "" ></exception-mapping></global-exception-mappings>

or mapping information or result information can also be placed in the Local:

<action name= "Login" class= "com.test.action.LoginAction" ><exception-mapping result= "Usernameinvalid" exception= "Com.test.exception.UsernameException" ></exception-mapping><result name= "Success" >/ Result.jsp</result><result name= "Input" >/login2.jsp</result></action>

Therefore, you can either local exception map/result (Mapping/result) or global mapping. Find the rules: first find the local, looking for the global.

Part 15th _struts2.1 Interceptor Depth analysis, exception handling

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.