Go SPRINGMVC Interceptor detailed [with source analysis]

Source: Internet
Author: User

Directory
    • Objective
    • Important interface and class introduction
    • SOURCE Analysis
    • Interceptor Configuration
    • Writing a custom Interceptor
    • Summarize
Objective

SPRINGMVC is currently one of the mainstream web MVC frameworks.

If a classmate is unfamiliar with it, then please refer to it's Getting started blog:http://www.cnblogs.com/fangjian0423/p/springmvc-introduction.html

Interceptors are a must-have feature for each web framework and are a commonplace theme.

This article will analyze how the interceptor function of SPRINGMVC is designed, and let the reader understand the principle of the function design.

Important interface and class introduction

1. Handlerexecutionchain class

Classes made up of Handlermethod and interceptor collections are obtained by the GetHandler method of the Handlermapping interface.

2. Handlerinterceptor interface

  

SPRINGMVC Interceptor Base interface.

3. abstracthandlermapping

Handlermapping the underlying abstract class.

4. Asynchandlerinterceptor

Inherits the Handlerinterceptor interface and provides an additional afterconcurrenthandlingstarted method, which is used to handle asynchronous requests. This method is triggered when there is an asynchronous request method in the controller. The landlord has done the test, the asynchronous request first supports Prehandle, then executes the afterconcurrenthandlingstarted. Executes Prehandle, Posthandle, aftercompletion after the asynchronous thread finishes. Interested readers can do their own research.

5. Handlerinterceptoradapter

An abstract class that implements the Asynchandlerinterceptor interface, which is typically inherited by the use of interceptors. The corresponding method is then replicated.

6. Webrequestinterceptor

Similar to the Handlerinterceptor interface, the difference is that the Webrequestinterceptor Prehandle has no return value. There is also webrequestinterceptor for the request, there is no response in the interface method parameter.

  

The interceptors inside Abstracthandlermapping is a collection of object types. When processing, it is determined that mappedinterceptor[joins to the Mappedinterceptors collection];handlerinterceptor, Webrequestinterceptor ( Fit into Webrequesthandlerinterceptoradapter) [Add to Adaptedinterceptors]

7. Mappedinterceptor

A class that includes the IncludePatterns and excludepatterns string sets combined with Handlerinterceptor. It is obvious that there are interceptors that are specifically included and excluded for some addresses.

8. Conversionserviceexposinginterceptor

The default <annotation-driven/> tag initialization is initialized with the Conversionserviceexposinginterceptor interceptor, and is constructed as a parameter to the constructor method. Mappedinterceptor. It is then added to the Abstracthandlermapping mappedinterceptors collection. The interceptor will drop the conversionservice in each request. Mainly used for the use of spring:eval tags.

SOURCE Analysis

First we look at how the interceptor is called.

After the Web request is Dispatcherservlet intercepted, the Dispatcherservlet Dodispatcher method is called.

It is clear that the Handlerexecutionchain method is called after the Handleradapter is processed and after processing is complete.

Handlerexecutionchain's Applyprehandle, Applyposthandle, and Triggeraftercompletion methods are as follows:

It is obvious that the internal implementation is called to handlerinterceptor the corresponding methods of the interface collection.

Let's look at the tectonic process of the handlerexecutionchain.

The Handlerexecutionchain is obtained from the GetHandler method of the Handlermapping interface.

Handlermapping in the underlying abstract class Abstracthandlermapping:

As we can see, the Handlerexecutionchain interceptor is obtained from the adaptedinterceptors and Mappedinterceptors attributes in the abstracthandlermapping.

Interceptor Configuration

Once you know how the Handlerexecutionchain interceptor property is constructed, here's how SPRINGMVC configures the interceptor.

1. Add <mvc:interceptors> Configure in *-dispatcher.xml configuration file

<Mvc:interceptors><mvc:interceptor> <mvc:mapping path="/** "/> <mvc:exclude-mapping path= "/login"/> <mvc:exclude-mapping path= "/index"/> < bean class= " Package.interceptor.XXInterceptor "/> </mvc:interceptor ></MVC:INTERCEPTORS>      

Each <mvc:interceptor> configured here will be parsed into mappedinterceptor.

where child tags <mvc:mapping path= "/**"/> will be parsed into Mappedinterceptor includepatterns properties; <mvc:exclude-mapping path= "/**"/ > will be parsed into Mappedinterceptor's Excludepatterns attribute;<bean/> will be parsed into the Interceptor attribute of Mappedinterceptor.

<mvc:interceptors> This tag is parsed by the Interceptorsbeandefinitionparser class.

2. Configure requestmappinghandlermapping and configure the Interceptors collection properties for that bean. The Interceptors collection here is an object-type generic collection.

The abstracthandlermapping abstract class exposes only 1 interceptor set methods, interceptors.

Both Adaptedinterceptors and mappedinterceptors do not expose the Set method, so we can only configure interceptors properties for requestmappinghandlermapping.

In fact abstracthandlermapping internal initinterceptors method, will traverse interceptors collection, and then determine whether each item is Mappedinterceptor, Handlerinterceptor, Webrequestinterceptor.

Where the Mappedinterceptor type of interceptor is added to the Mappedinterceptors collection, the Handlerinterceptor type is added to the Adaptedinterceptors collection, The Webrequestinterceptor type will be Webrequesthandlerinterceptoradapter added to the Adaptedinterceptors collection.

  

  

The configuration is as follows:

<bean class=  "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" > <property name=" interceptors "> <bean class= "Package.interceptor.XXInterceptor"/> </property> < Property name= "order" value=< Span class= "Hljs-value" "-1"/></BEAN>    

  Here is a property order, which is a 1. Why is it?

Actually, it's a little bit of knowledge to share with the readers.

Spring provides an order interface, mainly for sorting purposes.

  

The abstracthandlermapping abstract class we are using here also implements this interface.

Dispatcherservlet initializes the code of the Handlermapping collection:

Therefore, if the reader is also configured with:

  <mvc:annotation-driven/>

  Then there will be 2 handlermapping, so when we configure requestmappinghandlermapping, we set the order to 1, which is to give this handlermapping a higher priority than <MVC: The requestmappinghandlermapping level of the annotation-driven/> configuration.

If the reader has only configured requestmappinghandlermapping, the <mvc:annotation-driven/> is not configured. Then you can ignore this little knowledge ~~~~~~~~ 

It is generally recommended to use the first method. 

Writing a custom Interceptor
PublicClassLogininterceptorExtends Handlerinterceptoradapter {@OverridePublicBooleanPrehandle (HttpServletRequest request, httpservletresponse response, Object handler)Throws Exception {Gets the URI of the request path String URI = Request.getrequesturi ();Determine if the path is logout or login authentication, is one of the two, the method defined in the controller is executed if (Uri.endswith ("/login/auth") | | uri.endswith ("/login/out") {return true;} //Enter the login page, determine if there is a key in the session, some words redirect to the homepage, otherwise enter the login interface if (Uri.endswith ("/login/") | | uri.endswith ("/login") {if ( Request.getsession ()! = null && request.getsession (). getattribute ("Loginuser")! = null) { Response.sendredirect (Request.getcontextpath () + "/index"); } else { return true;}} //Other circumstances determine if there is a key in the session, and some continue the operation of the user if (request.getsession () = null && request.getsession (). getattribute ( "Loginuser") = null) { return true;} //The last situation is to enter the login page response.sendredirect (request.getcontextpath () + "/login"); return false;}}          

Login Controller:

@Controller@RequestMapping(value = "/login")public class LoginController { @RequestMapping(value = {"/", ""}) public String index() { return "login"; } @RequestMapping("/auth") public String auth(@RequestParam String username, HttpServletRequest req) { req.getSession().setAttribute("loginUser", username); return "redirect:/index"; } @RequestMapping("/out") public String out(HttpServletRequest req) { req.getSession().removeAttribute("loginUser"); return "redirect:/login"; } }

*-diapatcher.xml configuration:

<mvc:interceptors>  <mvc:interceptor>    <mvc:mapping path="/**"/> <bean class="org.format.demo.interceptor.LoginInterceptor"/> </mvc:interceptor></mvc:interceptors>

PS: We see that the Prehandle method in Logininterceptor is not processed for the address "/login/auth" and "/login/out".

Therefore, you can write a point configuration and write less Java code. Add 2 exclude-mapping to the Interceptor configuration and remove the Logininterceptor

if(uri.endsWith("/login/auth") || uri.endsWith("/login/out")) {  return true;}

Configuration additions:

<mvc:exclude-mapping path="/login/out"/><mvc:exclude-mapping path="/login/auth"/>
Summarize

summed up the principle of the SPRINGMVC interceptor and various configurations, like many people on the Internet will ask why the Interceptor execution Prehandle method returned false or will execute Aftercompletion method, in fact, we see the source code will know.

About interceptors for asynchronous requests and the second configuration method (Interceptors collection properties can be added to classes that inherit from Handlerinterceptoradapter abstract classes and classes that implement Webrequestinterceptor interfaces). Readers can do their own research.

There is inevitably a mistake in the text, hoping that the reader can point it out.

Go SPRINGMVC Interceptor detailed [with source analysis]

Related Article

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.