菜鸟之路——Spring MVC(五)ViewResolver

    在Spring MVC中,ViewResolver 用来将用户控制器生成的返回结果解析成视图,View定义了不同的视图,并渲染给用户,但是Spring是怎样工作的呢?现在我们就分析下Spring如何解析返回的结果生成响应的视图。

  一、概念

  View ---View接口表示一个响应给用户的视图,例如jsp文件,pdf文件,html文件等,它的定义如下
public interface View {
    //HttpServletRequest中的属性名,其值为响应状态码
    String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";
    //HttpServletRequest中的属性名,它的对应值是请求路径中的变量,及@PathVariable
    //注解的变量
    String PATH_VARIABLES = View.class.getName() + ".pathVariables";
    //该视图的ContentType
    String getContentType();
    //渲染该视图
    void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response);
}
      该接口只有两个方法定义,分别表明该视图的ContentType和如何被渲染。Spring中提供了丰富的视图支持,几乎包含所有你想得到的,并且Spring的视图拓展性很好,你可以轻松实现自己的视图。下面是View的一些实现类:
                  
   类结构图:
 
    ViewResolver --- ViewResolver接口定义了如何通过view 名称来解析对应View实例的行为,它的定义相当简单:
public interface ViewResolver {

    View resolveViewName(String viewName, Locale locale) throws Exception;
}
      该接口只有一个方法,通过view name 解析出View。同样Spring提供了丰富的ViewResolver实现用来解析不同的View:
              
   ViewResolver的类结构:

  二、怎么获取ModelAndView

  Spring是如何处理返回值并响应给客户呢?这就是这节要分析的,根据返回值解析出对应的视图。
 
private ModelAndView invokeHandleMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest webRequest = new ServletWebRequest(request, response);

        WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
        ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
        ServletInvocableHandlerMethod requestMappingMethod = 
                                    createRequestMappingMethod(handlerMethod, binderFactory);

        ModelAndViewContainer mavContainer = new ModelAndViewContainer();
        mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
        modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);
        mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

        AsyncExecutionChain chain = AsyncExecutionChain.getForCurrentRequest(request);
        chain.addDelegatingCallable(getAsyncCallable(mavContainer, modelFactory, webRequest));
        chain.setAsyncWebRequest(createAsyncWebRequest(request, response));
        chain.setTaskExecutor(this.taskExecutor);
        //调用了处理器方法并处理了返回值
        requestMappingMethod.invokeAndHandle(webRequest, mavContainer);

        if (chain.isAsyncStarted()) {
            return null;
        }
        //这里是根据返回值返回ModelAndView
        return getModelAndView(mavContainer, modelFactory, webRequest);
    }

     invokeAndHandle方法调用了处理器方法,并处理了返回值,剩下的就是如何将返回值呈现给用户了,我们看getModelAndView的实现:
 
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
            ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
        //主要是同步model属性,并且将BindingResult添加到model中来
        modelFactory.updateModel(webRequest, mavContainer);
        //是否直接处理请求,如@ResponseBody
        if (mavContainer.isRequestHandled()) {
            return null;
        }
        ModelMap model = mavContainer.getModel();
        ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model);
        if (!mavContainer.isViewReference()) {
            mav.setView((View) mavContainer.getView());
        }//如果model是RedirectAttributes,进行flashAttributes的处理
        /
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值