A schematic analysis of the Spring MVC request processing process (a)

Source: Internet
Author: User
Tags exception handling file upload json root directory
Preface

The Spring MVC framework is believed to be familiar to many people, and the information on this is a huge search. But the feeling speaks is not very meticulous, lets many beginners all foggy. I have done so, I have studied it before, but I don't have to find it again after some time. So I decided to write it down for later use.
This series is based on spring-4.3.1, configuration method all based on java-based mode from the configuration

First, the Configuration code:

@EnableWebMvc @Configuration public class Mvcconfig extends Webmvcconfigureradapter {@Override public void confi
    Guredefaultservlethandling (Defaultservlethandlerconfigurer configurer) {configurer.enable (); } @Override public void Configureviewresolvers (Viewresolverregistry registry) {registry.jsp ("/web-inf/js
        p/",". jsp ");
    Registry.enablecontentnegotiation (New Mappingjackson2jsonview ()); } @Override public void Configurecontentnegotiation (Contentnegotiationconfigurer configurer) {Configurer
                . Favorpathextension (True). Ignoreacceptheader (True). ParameterName ("mediatype") . Defaultcontenttype (mediatype.text_html). MediaType ("HTML", mediatype.text_html). Me
    Diatype ("JSON", Mediatype.application_json);
        } @Bean (name = "Multipartresolver")//File Upload Bean public commonsmultipartresolver commonsmultipartresolver () { return new CoMmonsmultipartresolver (); }
}

The

java-based-based spring MVC configuration requires creating a configuration class and implementing the Webmvcconfigurer interface Webmvcconfigureradapter The abstract class is a simple abstraction of the Webmvcconfigurer interface (adding some default implementations), so the configuration code above chooses to inherit Webmvcconfigureradapter directly. Then, according to the needs of the project to implement specific methods in the interface, finally, note that you want to label the @enablewebmvc on the configuration class.
Here someone might ask, how do I know what to implement. Exactly how to match it. How the process is handled between them. OK, don't worry, we'll step by step.
First step, we need to know which callback methods are provided by the Webmvcconfigurer interface. Webmvcconfigurer

Package org.springframework.web.servlet.config.annotation; /** * For reasons, we will introduce only some of the methods commonly used by spring MVC * * public interface Webmvcconfigurer {void Addformatters (Formatterregistry regi

    Stry);

    void Configuremessageconverters (list 

Here are a few common ways to focus on the following:

void Configureviewresolvers (Viewresolverregistry registry);
void Configurecontentnegotiation (Contentnegotiationconfigurer configurer);
void Addviewcontrollers (Viewcontrollerregistry registry);
void Addresourcehandlers (Resourcehandlerregistry registry);
void Configuredefaultservlethandling (Defaultservlethandlerconfigurer configurer);
1. Configureviewresolvers (Viewresolverregistry Registry)

From the method name we can see that this method is used to configure the view parser, the method parameter Viewresolverregistry is a registrar, used to register you want to customize the view parser and so on. Viewresolverregistry commonly used in several ways: 1). Enablecontentnegotiation

/** Enable Content Adjudication View Resolver *
/public void enablecontentnegotiation (view ... defaultviews) {
        Initcontentnegotiatingviewresolver (defaultviews);
    }

This method creates a content adjudication parser contentnegotiatingviewresolver, which does not parse the specific view, but manages all the view parsers that you have registered, all of which are parsed first. It then decides which parser to use for parsing. The specific mapping rules are determined based on the requested media types. 2). Urlbasedviewresolverregistration

    Public urlbasedviewresolverregistration jsp (string prefix, string suffix) {
        internalresourceviewresolver resolver = new Internalresourceviewresolver ();
        Resolver.setprefix (prefix);
        Resolver.setsuffix (suffix);
        This.viewResolvers.add (resolver);
        return new Urlbasedviewresolverregistration (resolver);
    }

The method registers an internal resource View parser that Internalresourceviewresolver apparently accesses all of the jsps that it parses. The method parameter is used to specify the prefix and file suffix of the path, such as:

    registry.jsp ("/web-inf/jsp/", ". jsp");

For the above configuration, if the returned view name is example, it will return/web-inf/jsp/example.jsp to the front end, and the report 404 cannot be found.
   3). Beanname

    public void Beanname () {
        Beannameviewresolver resolver = new Beannameviewresolver ();
        This.viewResolvers.add (resolver);
    }

This method registers a Beannameviewresolver view parser, which is what the parser is doing. It mainly resolves the view name to the corresponding bean. What do you mean? If the returned view name is example, it will find a bean called example in the spring container, and the bean is of type view.class. If so, return this bean.
   4). Viewresolver

    public void Viewresolver (Viewresolver viewresolver) {
        if (viewresolver instanceof Contentnegotiatingviewresolver) {
            throw new Beaninitializationexception (
                    "Addviewresolver cannot is used to configure a Contentnegotiatingviewresolver. Use the method enablecontentnegotiation instead. ");
        This.viewResolvers.add (Viewresolver);
    }

This method must be known by the name, it is used to register a variety of view parsers, including their own definition.
   2. Configurecontentnegotiation (contentnegotiationconfigurer configurer)

In the previous section we talked about the Configureviewresolvers method, if we enabled the Content award parser in this method, then Configurecontentnegotiation ( Contentnegotiationconfigurer Configurer) This method is specifically used to configure some parameters of the Content award. This is relatively straightforward, and we can look at it directly from an example:
  

   public void Configurecontentnegotiation (Contentnegotiationconfigurer configurer) {/
       * Whether the media type is determined by the extension of the request URL *
        /Configurer.favorpathextension (TRUE)/  
                 * Do not check the Accept request header *
                /. Ignoreacceptheader (True)
                . ParameterName ("mediatype")/
                 * Set the default media yype *
                /. Defaultcontenttype (mediatype.text_html)/
                 * Requests that end with. HTML will be treated as mediatype.text_html*/
                . MediaType ("HTML", mediatype.text_html)/
                * Requests that end with. JSON will be treated as mediatype.application_json*/
                . MediaType ("JSON", Mediatype.application_json);
    }

Here we can give an example to further familiarize ourselves with the above knowledge, if our MVC configuration is as follows:

    @EnableWebMvc
    @Configuration Public
    class Mvcconfig extends Webmvcconfigureradapter {

        @Override
        public void Configureviewresolvers (Viewresolverregistry registry) {
            registry.jsp ("/web-inf/jsp/", ". jsp");
            Registry.enablecontentnegotiation (New Mappingjackson2jsonview ());
        }

        @Override public
        void Configurecontentnegotiation (Contentnegotiationconfigurer configurer) {
            Configurer.favorpathextension (True).
                    Ignoreacceptheader (True).
                    parametername ("mediatype")
                    . Defaultcontenttype (mediatype.text_html)
                    . MediaType ("HTML", mediatype.text_html)
                    . MediaType ("JSON", Mediatype.application_json);
        }
    }

The controller's code is as follows:

    @Controller public
    class Examplecontroller {
         @RequestMapping ("/example1") public
         Modelandview example1 ( ) {
            map<string, string> Map = new HashMap ();
            Map.put ("1", "a");
            Map.put ("2", "B");
            return new Modelandview ("example1", map);
        }
    }

Create a example1.jsp file in the web-inf/jsp directory, free of content. Now launch Tomcat, enter the following link in the browser: Http://localhost:8080/example1.json, the browser returns as follows:
  
In the browser input http://localhost:8080/example1 or http://localhost:8080/example1.html, return as follows:

Obviously, two times a different view parser is used, so what happens at the bottom. In the configuration we registered two view parsers: Contentnegotiatingviewresolver and Internalresourceviewresolver, and a default view: Mappingjackson2jsonview. When the controller finishes executing, it returns a Modelandview with the name example1 of the view. The return is first given to contentnegotiatingviewresolver for view resolution processing, and Contentnegotiatingviewresolver The view name example1 is given to all the viewresolver it holds to try to parse (only internalresourceviewresolver in this instance), and then according to the mediatype of the request, Then the Example1.mediatype (here is Example1.json and example1.html) as the view name for all the view parser to parse again, after two steps resolved to get a bunch of candidate list<view> Add the default Mappingjackson2jsonview, and finally choose an optimal return from the candidate list<view> based on the media type requested, so that the view is resolved. Now you can understand why the request link plus. JSON and not. JSON results are different in the previous example. When you add. JSON, the media type that is requested is mediatype.application_json, and the contenttype of the view that internalresourceviewresolver resolves does not match. In accordance with Mappingjackson2jsonview's contenttype, the Mappingjackson2jsonview is returned as a view. When the. JSON request is not added, the default media type is mediatype.text_html, so the internalresourceviewresolver parsed view is used as the return value. I want to see here that you can already customize the view in general.3. Addviewcontrollers (Viewcontrollerregistry Registry)

This method can easily implement a request-to-view mapping without writing a controller, for example:
  

    @Override public  
    void Addviewcontrollers (Viewcontrollerregistry registry) {  
        Registry.addviewcontroller ("/ Login "). Setviewname (" login ");  
    

This is a direct return to the login page when accessing ${domain}/login. 4. Addresourcehandlers (Resourcehandlerregistry Registry)

This method is used specifically to register a handler to handle static resources, such as: Pictures, js,css, and so on. Example:
  

    @Override public
    void Addresourcehandlers (Resourcehandlerregistry registry) {
        Registry.addresourcehandler ( "/resource/**"). Addresourcelocations ("/web-inf/static/");
    }

When you request Http://localhost:8083/resource/1.png, you will return the/web-inf/static/1.png. Note : The static resources here are placed in the web-inf directory. 5. Configuredefaultservlethandling (defaultservlethandlerconfigurer configurer)

Usage:

    @Override public
    void configuredefaultservlethandling (Defaultservlethandlerconfigurer configurer) {
        Configurer.enable ();
    }

A default handler:defaultservlethttprequesthandler is registered, and the handler is also used to process the static file, which attempts to map/*. When the Dispatcherservelt mapping/(/and/* is differentiated) and no suitable handler is found to handle the request, it is handed to defaultservlethttprequesthandler for processing. Note : The static resources here are placed under the WEB root directory, not under web-inf .
Perhaps the description here is a bit difficult to understand (I think so), so simply give an example, for example: in the webroot directory has a picture: 1.png We know the Servelt specification in the Web root directory (webroot) files can be directly accessed, However, because dispatcherservlet configured the mapping path is:/, it almost all the requests are intercepted, resulting in 1.png access, then register a Defaultservlethttprequesthandler can solve this problem. It can be understood that Dispatcherservlet destroys a feature of the servlet (the file under the root directory can be accessed directly), and Defaultservlethttprequesthandler helps to return to this feature. Off Topic

Q: What is the difference between/and/*.
A:/Will intercept all url,/* except for JSP to intercept all URLs, including JSP . For example: Under Webroot There is a test.jsp, when the Dispatcherservlet configuration map/, browser input: http://localhost:8083/test.jsp This JSP is directly accessible, And without Dispatcherservlet, this request is intercepted by Dispatcherservlet when the Dispatcherservlet configuration map/*.

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.