I. Introduction of interceptors
Spring MVC's processor interceptors are similar to filter filters in servlet development for preprocessing and post-processing of processors. Common Application Scenarios
1, log records: Log the request information for information monitoring, information statistics, calculation of PV (Page View) and so on.
2, permission check: such as login detection, enter the processor detection detection is logged in, if not directly back to the login page;
3, performance monitoring: Sometimes the system in a certain period of time inexplicably slow, can pass through the interceptor before entering the processor before the start time, record the end time after processing, so as to get the processing time of the request (if there is a reverse proxy, such as Apache can automatically record);
4, general behavior: Read the cookie to get user information and put the user object into the request, so as to facilitate the subsequent use of the process, as well as the extraction locale, theme information, as long as the multiple processors are required to use the interceptor implementation.
5, Opensessioninview: such as Hibernate, enter the processor to open the session, after the completion of the session closed.
Nature is also AOP (aspect-oriented programming), meaning that all features that conform to crosscutting concerns can be put into the interceptor implementation. Second, the SPRINGMVC default controller 1, Dispatcherservlet
SPRINGMVC has a unified portal Dispatcherservlet, all requests are through Dispatcherservlet. The Dispatcherservlet is the predecessor controller, which is configured in the Web. xml file. Interception of matching requests, servlet intercept matching rules to be self-defined, the interception of requests, according to certain rules distributed to the target controller to deal with. So we now add the following configuration to Web. xml:
<servlet>
<servlet-name>springMybatis</servlet-name>
<servlet-class> Org.springframework.web.servlet.dispatcherservlet</servlet-class>
<load-on-startup>1</ load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMybatis< /servlet-name>
<!--All requests will be processed Dispatcherservlet-
<url-pattern>/</url-pattern>
</servlet-mapping>
When Dispatcherservlet is initialized, the framework looks for a file named]-servlet.xml in the Web application Web-inf directory, where the associated beans is defined, overriding any beans defined in the global. 2. Configuring static resource files does not intercept
If you only configure the interception of URLs similar to *.do format, then access to the static resources is not a problem, but if the configuration intercepts all requests (such as the "/" configured above), it will cause the JS files, CSS files, picture files and other static resources can not be accessed. The general implementation of the interceptor is mainly for the rights management, mainly to intercept some URL requests, so do not intercept static resources. There are generally two ways to filter out static resources.
The first is the use of <mvc:default-servlet-handler/> (the default servlet name for the Web application server is "default", So here we activate Tomcat's defaultservlet to handle the static file, in the Web. XML, configure the following code:)
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/js/*</ url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/images/*</ url-pattern>
<url-pattern>/fonts/*</url-pattern>
</servlet-mapping>
Tomcat, Jetty, JBoss, and GlassFish the default servlet name – "Default"
Resin default servlet name – "Resin-file"
WebLogic default servlet name – "Fileservlet"
The name of the WebSphere default servlet – "Simplefileservlet"
The second is to use <mvc:resources/>, add the following code to the SPRINGMVC configuration file:
<mvc:resources mapping= "/js/**" location= "/static_resources/javascript/"/> <mvc:resources
mapping= "/ styles/** "location="/static_resources/css/"/>
<mvc:resources mapping="/images/** "location="/static_ Resources/images/"/>
Iii. Custom Interceptors
In Springmvc, define the interceptor to implement the Handlerinterceptor interface and implement the three methods provided in the interface. 1. Interceptor Interface Handlerinterceptor
Package org.springframework.web.servlet;
Public interface Handlerinterceptor {
boolean prehandle (
httpservletrequest request, HttpServletResponse Response,
Object handler)
throws Exception;
void Posthandle (
httpservletrequest request, httpservletresponse response,
Object handler, Modelandview Modelandview)
throws Exception;
void Aftercompletion (
httpservletrequest request, httpservletresponse response,
Object handler, Exception Ex)
throws Exception;
}
Prehandle
Preprocessing callback method, implementation of processor preprocessing (such as login check), the third parameter is the response of the processor (such as the specific controller implementation);
Return value: True indicates continuation of the process (such as invoking the next interceptor or processor), false indicates a process interruption (such as a login check failure), and does not continue to invoke other interceptors or processors, at which point we need to generate a response by response; Posthandle
A post-processing callback method that implements post-processing of the processor (but before rendering the view), at which point we can process the model data by Modelandview (model and view objects) or the views, and Modelandview may also be null. Aftercompletion
The entire request is processed by the callback method, that is, the callback when the view is rendered, such as performance monitoring where we can record the end time and output the time consumed, as well as some resource cleanup, similar to the finally in Try-catch-finally, But only the aftercompletion of the Interceptor that Prehandle returns true in the processor execution chain is called. 2. Interceptor Adapter
Sometimes we may only need to implement one of the three callback methods, if the implementation of the Handlerinterceptor interface, three methods must be implemented, whether you need not, Spring provides a handlerinterceptoradapter adapter (an implementation of an adapter design pattern) that allows us to implement only the callback methods that are needed.
Public abstract class Handlerinterceptoradapter implements Handlerinterceptor {
//omit code here so three callback methods are empty implementations, Prehandle returns True.
Use the following methods:
Omit import public
class HandlerInterceptor1 extends Handlerinterceptoradapter {
// The Handlerinterceptoradapter adapter can be inherited here
@Override public
boolean prehandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println ("=========== HandlerInterceptor1 prehandle ");
return true;
}
@Override public
void Posthandle (HttpServletRequest request, httpservletresponse response, Object handler, Modelandview Modelandview) throws Exception {
System.out.println ("===========handlerinterceptor1 posthandle");
}
@Override public
void Aftercompletion (HttpServletRequest request, httpservletresponse response, Object Handler, Exception ex) throws Exception {
System.out.println ("===========handlerinterceptor1 aftercompletion");
}
}
Iv. Demonstration of the example
1. Custom Interceptors
This is the way to customize the interceptor by implementing an interface.
Defining interceptors 1
Test blocker 1 Public
class HandlerInterceptor1 implements handlerinterceptor{
@Override public
Boolean Prehandle (httpservletrequest request,
httpservletresponse response, Object handler) throws Exception {
System.out.println ("Handlerinterceptor1....prehandle");
False means interception, not execution down; True means release
return true;
}
@Override public
void Posthandle (HttpServletRequest request,
httpservletresponse response, Object handler,
Modelandview Modelandview) throws Exception {
System.out.println ("Handlerinterceptor1....posthandle");
}
@Override public
void Aftercompletion (HttpServletRequest request,
httpservletresponse response, Object handler, Exception ex)
throws Exception {
System.out.println ("HandlerInterceptor1 .... Aftercompletion ");
}
}
Defining interceptors 2
Test Blocker 2 Public
class HandlerInterceptor2 implements handlerinterceptor{
@Override public
Boolean Prehandle (httpservletrequest request,
httpservletresponse response, Object handler) throws Exception {
System.out.println ("Handlerinterceptor2....prehandle");
False means interception, not execution down; True means release
return true;
}
@Override public
void Posthandle (HttpServletRequest request,
httpservletresponse response, Object handler,
Modelandview Modelandview) throws Exception {
System.out.println ("Handlerinterceptor2....posthandle");
}
@Override public
void Aftercompletion (HttpServletRequest request,
httpservletresponse response, Object handler, Exception ex)
throws Exception {
System.out.println ("HandlerInterceptor2 .... Aftercompletion ");
}
}
2, the SPRINGMVC interceptor configuration
In Springmvc, interceptors are configured for specific handlermapping, that is, if an interception is configured in a handlermapping, the handler that is successful after the handlermapping mapping finally uses the interceptor. For example, assuming that the mapper we have configured in the configuration file is org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping, then we can configure the interceptor like this:
<bean class= "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" >
<property name= " Interceptors ">
<list>
<ref bean=" HandlerInterceptor1 "/>
<ref bean=" HandlerInterceptor2 "/>
</list>
</property>
</bean>
<bean id=" HandlerInterceptor1 "class=" Ssm.intercapter.HandlerInterceptor1 "/>
<bean id=" HandlerInterceptor2 "class = "Ssm.intercapter.HandlerInterceptor2"/>
Configure the global interceptor in SPRINGMVC as follows:
<!--configuring interceptors
--<mvc:interceptors> <!--multiple interceptors, in order--
<mvc:interceptor>
<mvc:mapping path= "/**"/> <!--means to intercept all URLs including child URL paths---
<bean class= " Ssm.interceptor.HandlerInterceptor1 "/>
</mvc:interceptor>
<mvc:interceptor>
<MVC : Mapping path= "/**"/>
<bean class= "Ssm.interceptor.HandlerInterceptor2"/>
</mvc:interceptor >
<mvc:interceptor>
<mvc:mapping path= "/**"/>
<bean class= " Ssm.interceptor.HandlerInterceptor3 "/>
</mvc:interceptor>
</mvc:interceptors>
In general, we use this configuration,<mvc:mapping> specify the URL to intercept. 3. Execution test of SPRINGMVC interceptor
Follow the above HandlerInterceptor1 to write two interceptors, HandlerInterceptor2 and HANDLERINTERCEPTOR3, CONFIGURED according to the above configuration. Then let's test the implementation of the three interceptors and make a summary. Three interceptors are released.
That is, we change the return value in the Prehandle method of the three interceptors to true to test the order of execution of the interceptor, and the test results are as follows:
Handlerinterceptor1....prehandle
handlerinterceptor2....prehandle
handlerinterceptor3....prehandle
Handlerinterceptor3....posthandle
handlerinterceptor2....posthandle
handlerinterceptor1....posthandle
Handlerinterceptor3....aftercompletion
handlerinterceptor2....aftercompletion
HandlerInterceptor1 .... Aftercompletion
Make a summary based on the printed results: When all interceptors are released, the Prehandle method is executed in the configured order, while the other two methods are reversed in the configured order. There's an interceptor that doesn't release.
We change the return value in the Prehandle method of the third interceptor to false, the first two or true to test the order of execution of the interceptor, and the test results are as follows:
Handlerinterceptor1....prehandle
handlerinterceptor2....prehandle
handlerinterceptor3....prehandle
Handlerinterceptor2....aftercompletion
handlerinterceptor1....aftercompletion
Make a summary based on the printed results:
1. Since interceptors 1 and 2 are released, the Prehandle of the Interceptor 3 can be performed. This means that the previous interceptor is released and the interceptor behind it can execute the prehandle.
2. Interceptor 3 is not released, so its two other methods are not executed. That is, if an interceptor does not release, then its two other methods will not be executed back.
3. The Posthandle method of all interceptors will not be executed as long as one interceptor is not released, but the Aftercompletion method will be executed as long as the Prehandle is executed and released. None of the three interceptors are released.
This situation can actually refer to the above situation, is a special case, also look at the results of the operation:
Handlerinterceptor1....prehandle
Obviously, only the Prehandle method of the first interceptor is executed, because none is released, so there is no one to execute the Posthandle method and Aftercompletion method. v. Use of interceptors
In the second case, such as now to write a unified exception handling logic, then to put the interceptor in the first position of the chain, and must be released, because only release, will be executed aftercompletion, and placed in the first interceptor chain, The Aftercompletion method is executed last to execute the logic of uniform exception handling inside. For example, the login authentication interceptor, placed in the Interceptor link in the first position (if there is a unified exception handling, it should be placed after the unification of exception processing). The permission check interceptor is placed after the login authentication interceptor (because the permission is verified after login). Here is a login-verified interceptor to illustrate how to use the SPRINGMVC interceptor. 1. Interceptor Idea
If the requested URL is a public address (a URL that can be accessed without landing), let the release.
Otherwise detects if the user session exists.
If the user session does not exist, jump to the landing page.
If the user session exists then release, continue the operation. 2, the realization of the login controller method
Login
@RequestMapping ("/login") Public
String Login (httpservletrequest request, string Username, string Password) throws Exception {
//actual to go and database matching//
....
Here it is assumed that the landing was successful
HttpSession session = Request.getsession ();
Session.setattribute ("username", username);
return "Redirect:queryItems.action";
}
Exit
@RequestMapping ("/logout") public
String Logout (HttpServletRequest request) throws Exception {
HttpSession session = Request.getsession ();
Session.invalidate ();
return "Redirect:queryItems.action";
}
3, the implementation of the login verification interceptor
//Test Interceptor 1 public class Logininterceptor implements handlerinterceptor{//execute before entering handler method can be used for identity authentication, identity authorization. If the authentication does not indicate that the user is not logged in, this method is required to intercept no more execution, otherwise release @Override public boolean prehandle (HttpServletRequest request, Ht Tpservletresponse response, Object handler) throws Exception {//Get the requested URL String url = request.getrequest
URI ();
Determines whether the URL exposes the address (the actual use will expose the address configuration to the configuration file)//This assumes that the public address is the address of the submission if (Url.indexof ("login.action") > 0) {
If the login is submitted, release return true;
}//Judge session HttpSession session = Request.getsession ();
Remove the user identity information from the session String username = (string) session.getattribute ("username");
if (username! = null) {return true; }//Execute here to indicate user identity needs authentication, jump to landing page request.getrequestdispatcher ("/web-inf/jsp/login.jsp"). Forward (Request, RESPO
NSE);
return false; }//Save space, omit the other two methods do not write, do not process}
Then configure the Interceptor:
<!--configuring interceptors
--<mvc:interceptors> <!--multiple interceptors, in order--
<mvc:interceptor>
<mvc:mapping path= "/**"/> <!--intercept all URLs including child URL paths--
<bean class= " Ssm.interceptor.LoginInterceptor "/>
</mvc:interceptor>
<!--other interceptors--
</MVC: Interceptors>
So when we arbitrarily request a URL, we will be captured by the interceptor we have just defined, and then we will determine whether there is user information in the session, and then skip to the landing page to let us log in:
<form action= "${pagecontext.request.contextpath}/login.action" method= "POST" >
user name: <input type= "Text" Name= "username"/><br>
password: <input type= "password" name= "password"/><br>
<input Type= "Submit" name= "Submission"/>
</form>