Spring View 解析渲染

Spring mvc架构图:

这里写图片描述
DispatcherServlet:
1. doGet()/doPost()
2. doService()
3. doDispatch()核心方法
4. processDispatchResult()主要处理异常、请求状态及触发请求完成事件
5. render()图的渲染

源码

视图解析

 protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // Determine locale for request and apply it to the response.
        Locale locale = this.localeResolver.resolveLocale(request);
        response.setLocale(locale);

        // 定位view并且获取
        View view;
        if (mv.isReference()) {
            // ViewResolver接口定义了如何通过view 名称来解析对应View实例的行为
            view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
            ...
        }
        else {
            // 先到缓存中查找,若没有则创建
            // 在创建视图前会检查返回值是否是以:"redirect:""forward:" 开头的。
            // 如果是重定向:则创建一个重定向视图,返回创建的视图。如果是转发:则返回通过 转发 url 创建的 InternalResourceView 视图。
            // No need to lookup: the ModelAndView object contains the actual View object.
            view = mv.getView();
            ...
        }
        // 进行View的渲染
        try {
            view.render(mv.getModelInternal(), request, response);
        }
        catch (Exception ex) {
            ...
        }
    }

视图渲染

    public void render(Map<String, ?> model, HttpServletRequest request, 
                                                HttpServletResponse response) throws Exception {
        // 创建整合后需要返回给浏览器的Model  
        Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
        // 设置response 报文头
        prepareResponse(request, response);
        // 渲染数据,这个留给InternalResourceView来实现
        renderMergedOutputModel(mergedModel, request, response);
    }

有三种情况redirect视图,forward视图,普通视图,进行了不同处理
JstlView:

    protected void renderMergedOutputModel(  
            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {  
        // 将model中的数据设置到request(因为不见得所有数据都是通过request.setAttribute加入的)  
        exposeModelAsRequestAttributes(model, request);  
        // 本类中的此函数是空函数,留给子类比如JstlView去实现自定义逻辑  
        exposeHelpers(request);  
        // 设置跳转目的页面路径  
        String dispatcherPath = prepareForRendering(request, response);  
        // 获取跳转控制器RequestDispatcher  
        RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);  
        ...
        // 决定跳转到另一个控制器即forward操作还是返回用户请求资源,  
        // 如果用户设置或配置INCLUDE_REQUEST_URI_ATTRIBUTE  
        // 属性或response已经提交数据则直接返回资源给用户  
        if (useInclude(request, response)) {  
            response.setContentType(getContentType());  
            ...
            rd.include(request, response);  
        }       
        else {  //携带request和response跳转到另一个控制器方法  
            ... 
            rd.forward(request, response);  
        }  
    }  
    forward 跳向服务器的servlet, JSP文件, 或者 HTML文件。
    Includes 响应写入源文件 - servlet, JSP page,HTML file

这一步完成后SpringMVC就基本上完成自己的使命了,当找到对应的url路径,springmvc就继续访问url对应的servlet,剩下的渲染工作就交由Servlet去处理了,所以由此我们不难看出,springmvc实际是在tomcat和servlet中间加了一层,处理request将浏览器传递的参数封装成model再由应用来加工处理这些数据后,再将这些数据传递给servlet让servlet将这些经过应用处理的数据在页面上表现出来,从而完成web请求,目的在于页面和数据分离即页面表现和业务逻辑的分离,使开发中可以集中精力处理业务逻辑提高开发效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值