zoukankan      html  css  js  c++  java
  • springmvc DispatchServlet初始化九大加载策略(三)

     

    7. initRequestToViewNameTranslator 请求视图名

    它主要与视图解析有关,如果对ViewResolvers、ModelAndView、View等没有多大印象,可以先看第8节。

    RequestToViewNameTranslator主要是获取请求中的viewName,然后可以根据这个viewName获取ModelAndView对象。

    RequestToViewNameTranslator接口定义:

    public interface RequestToViewNameTranslator {
    
    	// Strategy interface for translating an incoming HttpServletRequest into a logical view name when no view name is explicitly supplied.
    	String getViewName(HttpServletRequest request) throws Exception;
    
    }

    简单的来说就是根据request请求获取来组装视图名称,仅此而已。

    在DispatcherServlet的doDispatch函数中会设置默认的视图名:

    // 设置默认的视图名称
    applyDefaultViewName(processedRequest, mv);
    applyDefaultViewName中会判断ModelAndView的hasView为空时,就设置viewName:
    
    if (mv != null && !mv.hasView()) {
        mv.setViewName(getDefaultViewName(request));
    }
    

      

    8. initViewResolvers 视图解析器

    ViewResolvers是一个List<ViewResolver>类型数据,视图解析是链式的,如果一个视图解析器根据viewName和local参数没有找到对应的View,则开始使用第二的解析器来进行查询,直到找到为止。默认的ViewResolvers为InternalResourceViewResolver:

    org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

    ViewResolver的作用就是通过解析viewName返回一个View对象:

    public interface ViewResolver {
        View resolveViewName(String viewName, Locale locale) throws Exception;
    }

    前文指出HandlerAdapter处理Handler请求,会返回一个视图对象ModelAndView。如果这个MdoelAndView Object类的View对象是String实例,则通过ViewResolver接口实现类的resolveViewName方法来转换为View类型,如果MdoelAndView Object类的View对象是Viwe实例,通过getter方法就可以获取View对象。

    ModelAndView类的属性定义如下:

    public class ModelAndView {
        // 两种设置方式,1:String类型  2:View类型。通过isReference()来区分
        // 如果view是String类型,则通过ViewResolver接口实现类的resolveViewName方法来转换为View类型
        private Object view;
        // LinkedHashMap<String, Object>类型
        private ModelMap model;
        private HttpStatus status;
        private boolean cleared = false;
        ...
        
    }

    获取到View对象之后,调用View的render方法进行页面渲染。

    具体的过程如下:

    当请求到达doDispatch后HandlerAdapte处理请求,返回一个MdoelAndView对象mv,然后调用:

    this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);

    该方法中主要调用render(mv, request, response),它会检查view是什么类型,如果是String类型,则通过ViewResolver接口实现类的resolveViewName方法来转换为View类型,总之最后要获取View实例对象, 调用View接口实现类的render方法,实现页面渲染:

    public interface View {
        String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
        String PATH_VARIABLES = View.class.getName() + ".pathVariables";
        String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";
    
        String getContentType();
        
        // @param model Map with name Strings as keys and corresponding model
        void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
    }

    常用的View实现类有:

    如果想看一个View渲染的具体流程可以参考《InternalResourceView源码分析(待写)》

    ps:不同视图对应不同的视图解析器,如FreeMarkerView就需要FreeMarkerViewResolver来完成解析。

     

     

    9. initFlashMapManager 重定向属性存储

    官方文档中指出:FlashMapManager用于检索和保存FlashMap实例的策略界面

    那FlashMap是什么呢?

    看看官方文档描述:

    /**
     * A FlashMap provides a way for one request to store attributes intended for
     * use in another. This is most commonly needed when redirecting from one URL
     * to another -- e.g. the Post/Redirect/Get pattern. A FlashMap is saved before
     * the redirect (typically in the session) and is made available after the
     * redirect and removed immediately.
     *
     * <p>A FlashMap can be set up with a request path and request parameters to
     * help identify the target request. Without this information, a FlashMap is
     * made available to the next request, which may or may not be the intended
     * recipient. On a redirect, the target URL is known and a FlashMap can be
     * updated with that information. This is done automatically when the
     * {@code org.springframework.web.servlet.view.RedirectView} is used.
     *
     * <p>Note: annotated controllers will usually not use FlashMap directly.
     * See {@code org.springframework.web.servlet.mvc.support.RedirectAttributes}
     * for an overview of using flash attributes in annotated controllers.
     *
     * @author Rossen Stoyanchev
     * @since 3.1
     * @see FlashMapManager
     */
    @SuppressWarnings("serial")
    public final class FlashMap extends HashMap<String, Object> implements Comparable<FlashMap> {
        ...
    }

    简单翻译:

    FlashMap为一个请求提供了一种存储属性的功能,用于另一个请求中使用这些属性。这种方式通常在 一个URL重定向到另一个URL时最常需要 - 例如Post / Redirect / Get模式。FlashMap在重定向之前保存(通常在会话中),并在重定向后可用并立即删除。

    可以使用请求路径和请求参数来设置FlashMap,以帮助识别目标请求。如果没有此信息,FlashMap将可用于下一个请求(该请求可能是也可能不是预期)。在一个重定向中,目标URL是已知的,可以使用该信息更新FlashMap,这个过程是自动完成的,它通过org.springframework.web.servlet.view.RedirectView完成此操作。

    注意:带注释的控制器通常不会直接使用FlashMap。 有关在带注释的控制器中使用Flash属性的概述,请参阅org.springframework.web.servlet.mvc.support.RedirectAttributes。

    通过上面的描述可知,FlashMap和FlashMapManager主要用于重定向数据保存。重定向就不得不提到RedirectView,RedirectView跳转时会将跳转之前的请求中的参数保存到FlashMap中,然后通过FlashManager保存起来:

    //获取原请求所携带的数据  
    FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request); 
    
    //将数据保存起来,作为跳转之后请求的数据使用  
    flashMapManager.saveOutputFlashMap(flashMap, request, response);

    当重定向的请求在浏览器中重定向之后会再次会被DispathcerServlet进行拦截,在DispatcherServlet的doService方法中,有一步会从FlashManager中获取保存的FlashMap中的值:

    FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);

    这样重定向的请求就可以使用以前的一些属性值了。

    总结:

    FlashMap简单来说就是一个HashMap,用于数据保存,主要作用于重定向,springMVC中默认的FlashMapManager为SessionFlashMapManager

    org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

     

    (全文完)

     

  • 相关阅读:
    深信服入职前编码训练21题--02
    深信服入职前编码训练21题--01
    Leetcode本地阅读器开发--01界面设计三
    Leetcode本地阅读器开发--01界面设计二
    Leetcode本地阅读器开发--01界面设计一
    使用DDMS测试安卓手机APP的性能(android)
    在PC上测试移动端网站和模拟手机浏览器的5大方法
    SeleniumIDE与eclipse如何连接使用
    Selenium RC配置
    Selenium IDE- 不同的浏览器
  • 原文地址:https://www.cnblogs.com/chenjunjie12321/p/9357678.html
Copyright © 2011-2022 走看看