The previous articles were all source code analysis for specific components in SpringMVC; This article is intended to supplement the documentation of the nine components in SpringMVC. This pulls out some of the basic components of HandlerMapping in addition to the previous articles.

The architecture of the DispatcherServlet class has been briefly introduced before, so I won’t go into it here. In the DispatcherServlet class, the MVC subcontainer initializes nine components, which will be explained later. To see how initialization is done in DispatcherServlet, post this code:

protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}

protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}
Copy the code

The onRefresh method in the above code is the entry method to the DispatcherServlet. In onRefresh, the initialization logic of each component is integrated by calling the initStrategies method. Personally, it is actually a policy set strategy, in which the responsibilities are also clear.

In the initStrategies method, specific initialization is done by calling the respective initialization methods of components. This is where you can clearly see the nine component names in SpringMVC. Here’s a look at the basic responsibilities of each of the nine components.

HandlerMapping

Handlermapping has been introduced in the following articles, but it is not complete. The subclasses of HandlerMapping have not been analyzed, and this will be updated later.

  • SpringMVC source series: HandlerMapping
  • SpringMVC source code series: AbstractHandlerMapping
  • For SpringMVC source series: AbstractUrlHandlerMapping

In the case of HandlerMapping, this is to find the corresponding Handler and Intecepter interceptor based on the request. Specific details of the parameters above the first article.

HandlerAdapter

If HandlerMapping is a pen, then HandlerAdapter is the person who uses the pen. In other words, a HandlerAdapter is a person who uses a processor to do things. Why is that? Take a look at the code:

public interface HandlerAdapter {
    boolean supports(Object var1);
    ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
    long getLastModified(HttpServletRequest var1, Object var2);
}
Copy the code

The HandlerAdapter interface provides a method called Handle. The third parameter of the Object handler parameter is actually a processor. The handle method uses the handler to process logic. After processing, a ModelAndView is returned.

HandlerExceptionResolver

HandlerExceptionResolver sets the ModelAndView based on the exception and then passes the result to the Render method. Of course render is only responsible for rendering the ModelAndView into a page, it doesn’t care where the ModelAndView comes from.

What if an exception occurs during rendering? From the above analysis, we can clearly know that the processing result of HandlerExceptionResolver is ModelAndView, and then render by the render method. That is, HandlerExceptionResolver works before rendering, so if exceptions occur during rendering, HandlerExceptionResolver will not handle them.

public interface HandlerExceptionResolver {
    ModelAndView resolveException(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4);
}
Copy the code

There is also only one method in HandlerExceptionResolver, which is to resolve the ModelAndView from the exception.

ViewResolver

The ViewResolver resolves a String View into a View based on local. The ViewResolver interface is defined as follows:

public interface ViewResolver {
    View resolveViewName(String viewName, Locale local) throws Exception;
}
Copy the code

As you can see from the code, there is only one method in the ViewResolver. The function of the resolveViewName method is explained by the parameters and return result of the resolveViewName method.

  • ViewName viewName of the String type
  • The local region can be used for internationalization.

The View is actually used to render the page, that is, to fill the results returned by the program into concrete templates to generate concrete View files, such as JSP, FTL, HTML, etc.

But there are two problems:

  • What template to use?
  • How to fill in the parameters?

Of course, these are the same problems that ViewResolver needs to solve in this section. There are basically two kinds:

A parser for a single view type

  • InternalResourceViewResolver
  • FreeMarkerViewResolver

The above two is to use most, InternalResourceViewResolver used to resolve the JSP, and FreeMarkerViewResolver is aimed at a FreeMarker.

For parsers that parse multiple types of views simultaneously

  • BeanNameViewResolver

    You need to use both the view name and the corresponding local to resolve the view. It needs to configure each view name and corresponding view type into the corresponding Properties file. (See details of component implementation below)

  • XmlViewResolver

    XmlViewResolver is a bit like BeanNameViewResolver, which uses a configuration file in XML format.

  • ResourceBundleViewResolver

    This is basically looking up the bean from the Spring container based on the viewName, and then finding the corresponding view based on the bean.

LocalResolver

As mentioned in the ViewResolver above, parsing a view requires two parameters, one of which is the logical view name of type String and the other is local. LocalResolver resolves local from request.

public interface LocaleResolver {
    Locale resolveLocale(HttpServletRequest request);

    void setLocale(HttpServletRequest request, HttpServletResponse response, Locale local);
}
Copy the code

The first method resolves local from the request, and the second method sets local to the request.

In most cases, local is used for internationalization.

ThemeResolver

Parsing the topic. This is something I rarely extend myself, even if I change themes, except for the functionality provided by SpringMVC itself. But there must be a reason for it. For our common web interface or mobile interface, a set of themes is nothing more than another set of images, CSS style files and so on. We can achieve this function through ThemeResolver. The specific use is actually equipped with a set of properties files for the system to read and switch at different times; Of course you can use this to internationalize as well.

public interface ThemeResolver {
    String resolveThemeName(HttpServletRequest request);

    void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName);
}
Copy the code

RequestToViewNameTranslator

This is actually quite interesting, which is to convert the request request to the view name.

public interface RequestToViewNameTranslator {
    String getViewName(HttpServletRequest request) throws Exception;
}
Copy the code

RequestToViewNameTranslator only a default implementation class DefaultRequestToViewNameTranslator.

The specific implements the DefaultRequestToViewNameTranslator getViewName (it request) method:

public String getViewName(HttpServletRequest request) {
    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
    return this.prefix + this.transformPath(lookupPath) + this.suffix;
}
Copy the code

This is done by delegating to the urlPathHelper class to get the suffix name of the request, such as /glmapper/login.do, by converting the request path to /login.do. Specific examples of how to convert to a view will also be provided later in the component introduction.

MultipartResolver

This corresponding partners are not unfamiliar, do website more or less will involve file upload. MultipartResolver is used to handle upload requests. Its approach is to request packaging into MultipartHttpServletRequest. And then we can use the direct call MultipartHttpServletRequest getFile access file.

FlashMapManager

This is needed for parameter passing at redirect.

public interface FlashMapManager {
    FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);

    void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}
Copy the code

RetrieveAndUpdate this method is used to retrieve parameters, both recovered and timeout parameters will be deleted.

The saveOutputFlashMap method is used to save parameters.

The default implementation mechanism of FlashMapManager is to store parameters in the session. I worked on a project where we could save parameters we didn’t want exposed in the URL using @redirectAttributes when forwarding the request and retrieve them from the next processor.

summary

This paper is mainly to do a general introduction to the nine components, the details of implementation and cases are not involved; Take a closer look at the implementation details of each component in a subsequent SpringMVC source code series.