SPRINGMVC processing static file source code Analysis

Source: Internet
Author: User

SPRINGMVC handles static resources, mainly two tags, mvc:resources and mvc:default-servlet-handler. Before detailing their rationale, it is necessary to briefly explain the request processing mechanism in the following springmvc: Handlermapping and Handleradapter.

1 handlermapping and Handleradapter.

The Python Django framework has been used to know that Django's configuration of access mode is that a URL path and a function pair, you access this URL, you will call this function directly, simple and clear

However, for the SPRINGMVC framework, due to the Java object-oriented, we need to find the corresponding class and corresponding method, so it needs to be divided into 2 steps.

    • The first step is to find the URL corresponding to the processing class, called Handler, here to use handlermapping to find

    • After we find the corresponding handler in the second step, which method do we call this handler? It's going to take Handleradapter to decide.

2 Common Handlermapping and Handleradapter simple introduction2.1 Handlermapping Interface Design and implementation
public interface HandlerMapping {    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;}

According to request, it is a combination of handler and interceptors to find the corresponding handlerexecutionchain,handlerexecutionchain. As follows:

public class HandlerExecutionChain {    private final Object handler;    private List<HandlerInterceptor> interceptorList;}

That is, for a request, there will be a corresponding handler and interceptors to handle. Handlermapping simply finds the corresponding handler and interceptors, it does not limit the type of handler, and any bean that exists in the spring IOC container can be handler, so this handler is an object.

Here's a look at a few common handlermapping implementations:

    • Beannameurlhandlermapping: Configure a Bean directly on the URL as the handler for this URL. As in XML, configure the following

      <bean name="/index" class="com.lg.mvc.HomeAction"></bean>

      When we visit Http://localhost:8080/index, we find this bean directly as a handler.

    • Simpleurlhandlermapping: The above can only configure a URL corresponding to the bean,simpleurlhandlermapping to configure multiple, more powerful, it has a map urlmap inside, The corresponding handler of each URL are stored, as follows

      <bean id="handler1" class="XXXX"/><bean id="handler2" class="XXXXX"/><bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">     <property name="urlMap">         <map>            <entry key="/user/login.do" value-ref="handler1"/>            <entry key="/admin/admin.do" value-ref="handler2"/>         </map>     </property></bean>
2.2 Handleradapter Interface Design and implementation
public interface HandlerAdapter {    boolean supports(Object handler);    ModelAndView handle(HttpServletRequest request, HttpServletResponse response,             Object handler) throws Exception;}

According to Handlermapping found handler, which method should we call handler? What are the methods of handler? In this case, we need to use the adapter mode to handle different handler. So Handleradapter supports method first to determine whether this handler is I can support, if I can support, then I will follow my processing mode, that is, call the above handle method.

Here's a look at some of the common Handleradapter implementations:

  • Simpleservlethandleradapter: The handler that it supports must be a servlet, so that the handler is bound to have a service (request, response) method, So we call handler's service (request, response) method to process the request, the source code is as follows

      public class Simpleservlethandleradapter Implements Handleradapter {@Override public boolean supports (Object handler) {return (handler instanceof Se    Rvlet); } @Override public Modelandview handle (httpservletrequest request, httpservletresponse response, Object        Handler) throws Exception {(Servlet) handler). Service (request, response);    return null; }}
  • Simplecontrollerhandleradapter: The handler that it supports must be a Controller,controller interface that defines a Modelandview handlerequest ( HttpServletRequest request, HttpServletResponse Response) method, so we know that the handler must have a HandleRequest method, call it to process the request, the source code is as follows

      public class Simplecontrollerhandleradapter implements Handleradapter {@Override public boolean supports (Object handler)    {return (handler instanceof Controller); } @Override public Modelandview handle (httpservletrequest request, httpservletresponse response, Object    Handler) throws Exception {return (Controller) handler). HandleRequest (request, response); }}
  • Httprequesthandleradapter: The handler that it supports must be a Httprequesthandler,httprequesthandler interface that defines a void HandleRequest ( HttpServletRequest request, HttpServletResponse Response) method, so we know that call this handler HandleRequest method, the source code is as follows:

      public class Httprequesthandleradapter implements Handleradapter {@Override public boolean supports (Object ha    Ndler) {return (handler instanceof Httprequesthandler); } @Override public Modelandview handle (httpservletrequest request, httpservletresponse response, Object        Handler) throws Exception {(Httprequesthandler) handler). HandleRequest (request, response);    return null; }}

The above several handlermapping and Handleradapter belong to SPRINGMVC original design idea. That is, handlermapping and handleradapter have no relationship, Handlermapping is only responsible for finding the corresponding Handler,handleradapter is responsible for finding the handler of which method. However, with the advent of annotations, that is, @requestmapping annotations directly callout requests corresponding to a certain method of a class, so that later handlermapping and Handleradapter Defaultannotationhandlermapping, Annotationmethodhandleradapter, requestmappinghandlermapping, Requestmappinghandleradapter (the former two have been replaced by the latter two) is no longer like the previous idea, began to scramble for power, requestmappinghandlermapping in the search for the corresponding handler, Not only to match the corresponding handler, but also to find the corresponding method. Their specific details can refer to my previous blog Mvc:annotation-driven and those of @controller and @requestmapping.

The next turn is the key (the top is long enough, haha)

3 Mvc:resources Source Analysis

Look at the general use of Mvc:resources, as follows:

<mvc:resources location="/WEB-INF/views/css/**" mapping="/css/**"/>

Then look at the source code. The first thing to declare again, all the tags configured in XML, will have the corresponding Beandefinitionparser implementation class to handle, for the mvc:resources tag, The corresponding implementation class is Resourcesbeandefinitionparser, look at the source code (no longer listed here, go to the self-view), you can know

A simpleurlhandlermapping has been registered (mentioned above). It has a map urlmap, which takes the mapping attribute in the mvc:resources tag as key and Resourcehttprequesthandler as the handler. That is,/css/** a similar URL request, which is matched by this simpleurlhandlermapping to Resourcehttprequesthandler.

Again, what is the method that calls Resourcehttprequesthandler to process the request?

Resourcehttprequesthandler implements the Httprequesthandler, which is the handler type supported by the Httprequesthandleradapter mentioned above, So it calls Resourcehttprequesthandler's void HandleRequest (HttpServletRequest request, HttpServletResponse response) method

In fact, it is easy to understand that Resourcehttprequesthandler will use the Location attribute in the mvc:resources tag as the directory, to find the corresponding resource, and then return the contents of the resource. This is no longer explained in detail, you can view the Resourcehttprequesthandler implementation of the HandleRequest method.

4 Mvc:default-servlet-handler Source Analysis

Similarly, the Beandefinitionparser implementation class for the Mvc:default-servlet-handler tag corresponds to Defaultservlethandlerbeandefinitionparser.

The simpleurlhandlermapping is registered here, and its map UrlMap contains a key of/* , corresponding to the handler for Defaultservlethttprequesthandler. That is, when the request path matches/ *, this simpleurlhandlermapping will be handed to Defaultservlethttprequesthandler to handle. This situation is generally other handlermapping can not match processing, finally helpless to Defaultservlethttprequesthandler.

Look at how Defaultservlethttprequesthandler is handled:

It also implements the Httprequesthandler interface, which has the void HandleRequest (HttpServletRequest request, HttpServletResponse Response) method, as follows:

@Overridepublic void handleRequest(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException {    RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);    if (rd == null) {        throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet ‘" +                this.defaultServletName +"‘");    }    rd.forward(request, response);}

As we can see, this is actually a servlet that is forwarded to the Web container itself. This servlet name can be configured in the Mvc:default-servlet-handler tab, if not configured, with the default configuration, as follows:

/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish */private static final String COMMON_DEFAULT_SERVLET_NAME = "default";/** Default Servlet name used by Google App Engine */private static final String GAE_DEFAULT_SERVLET_NAME = "_ah_default";/** Default Servlet name used by Resin */private static final String RESIN_DEFAULT_SERVLET_NAME = "resin-file";/** Default Servlet name used by WebLogic */private static final String WEBLOGIC_DEFAULT_SERVLET_NAME = "FileServlet";/** Default Servlet name used by WebSphere */private static final String WEBSPHERE_DEFAULT_SERVLET_NAME = "SimpleFileServlet";

That is, Tomcat, jetty, and so on, when the container starts, it will default to register a servlet name called default, you can learn from my previous article on Tomcat Url-pattern source analysis. Defaultservlethttprequesthandler is forwarded to these servlets.

In fact, this time, the request through the tomcat of the servlet Url-pattern match, into the SPRINGMVC, and then through Springmvc handlermapping a series of matches, there is no corresponding handler match, Cause again to be forwarded to the default servlet, such as Tomcat, around a large bend, so try to avoid such operations.

5 combining Tomcat's url-pattern to synthesize cases

Here is a case for analysis, in the Tomcat publishing root directory, there is a a.html and a.jsp file, and a SPRINGMVC project, as follows:

Where the SPRINGMVC project is configured with the Mvc:default-servlet-handler tag, the next two configurations are described in Springmvc Dispatcherservlet, namely

/ 和 /* 两种方式

The results were:

    • When the Dispatcherservlet is configured to/, both a.html and a.jsp can be accessed normally, as follows


    • Dispatcherservlet configured AS/*, a.html can normally access, a.jsp will not be, as follows


The analysis is as follows:

We know that priority is greater than . JSP priority, *.jsp priority is greater than/(can be learned by my previous article about Tomcat's Url-pattern source code analysis), in this context

When accessing a.html:

    • When Dispatcherservlet is configured for/, Tomcat will still choose Springmvc's dispatcherservlet to handle a.html-, and it cannot handle the MVC given the default configuration: Default-servlet-handler to process-"forward to Tomcat default servlet, i.e. Defaultservlet to process-" defaultservlet to find out if there is no file, found, return file contents
    • When Dispatcherservlet is configured AS/*, Tomcat still chooses Springmvc's dispatcherservlet to handle a.html, the same process as above

When accessing a.jsp:

    • When Dispatcherservlet is configured for/, Tomcat will prefer to process the jspservlet that it has already registered by default-"Jspservlet translate the file contents, return
    • When Dispatcherservlet is configured AS/*, Tomcat chooses SPRINGMVC's dispatcherservlet to handle a.jsp-"discovery Springmvc cannot find a matching handler to the configured MVC: Default-servlet-handler-"forwards to Tomcat's default servlet, Defaultservlet to process-" Defaultservlet only returns a.jsp source content

SPRINGMVC processing static file source code Analysis

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.