View 渲染
在Spring MVC 中,controllers不负责具体的页面渲染,仅仅是调用业务逻辑并返回model数据给view层,至于view层具体怎么展现,由专门的view层具体负责,这就是MVC模式,业务层与展示层是松耦合的。那么,Spring MVC是如何解耦合请求处理逻辑和页面渲染的呢?
视图解析器
请求进入DispathServlet后,通过HandlerMapping找到对应的HandlerExecutionChain,
最后交由HandlerAdapter来执行最终Handler【也就是Controller中的Action】,最终得到ModelAndView,然后再次交给DispatchServlet来处理,并执行render方法处理渲染逻辑,如下:
1protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
2 Locale locale =
3 (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
4 response.setLocale(locale);
5
6 View view;
7 String viewName = mv.getViewName();
8 if (viewName != null) {
9 // 通过ViewResolver 来获取真正的View对象
10 view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
11
12 }
13 }
14 else {
15 view = mv.getView();
16 }
17 }
18 try {
19 if (mv.getStatus() != null) {
20 response.setStatus(mv.getStatus().value());
21 }
22 //通过执行View对象的render方法来真正执行视图渲染的逻辑
23 view.render(mv.getModelInternal(), request, response);
24 }
25 catch (Exception ex) {
26 throw ex;
27 }
28 }
1 protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
2 Locale locale, HttpServletRequest request) throws Exception {
3
4 if (this.viewResolvers != null) {
5 for (ViewResolver viewResolver : this.viewResolvers) {
6//遍历ViewResolver集合 来获取合适的ViewResolver 对象
7 View view = viewResolver.resolveViewName(viewName, locale);
8 if (view != null) {
9 return view;
10 }
11 }
12 }
13 return null;
14 }
Spring MVC其实就是通过遍历ViewResolvers这种视图解析器集合,根据视图名来找到找到真正的物理视图【view页面】,对于普通的JSP页面,最常用到的view resolver就是InternalResourceViewResolver,它有两个属性,一个是匹配物理view的前缀,一个是后缀。前缀一般就是view页面的路径位置,后缀就是文件的格式,而前缀后缀之间的就是逻辑view名称。
1<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
2 <property name="prefix" value="/WEB-INF/views/" />
3 <property name="suffix" value=".jsp" />
4</bean>
5
比如按照上面的配置,如果controller返回的逻辑view名称是home的话,InternalResourceViewResolver会根据这个逻辑view名home找到其对应的实际物理view:/WEB-INF/views/home.jsp。
下面我们在看下视图解析器的定义如下,就一个方法resolveViewName,根据视图名称和Local对象得到最终的View视图
1public interface ViewResolver {
2 @Nullable
3 View resolveViewName(String viewName, Locale locale) throws Exception;
4}
视图渲染
如上,通过视图解析器ViewResolver 最终会得到视图View,然后会通过调用View对象的render方法来真正执行视图渲染的逻辑,View对象的定义如下
1public interface View {
2
3 String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";
4
5
6 void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
7 throws Exception;
8
9}
不同的实现类有不同的视图效果:
1、VelocityView是用来和Velocity框架结合生成页面视图
2、FreeMarkerView是用来和FreeMarker框架结合生成页面视图
3、JstlView是用来生成jstl页面
4、RedirectView是生成页面跳转视图的。
看下View的实现逻辑AbstractView源码如下
1 public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
2 HttpServletResponse response) throws Exception {
3
4//将model和request中的参数全部放到mergedModel中
5Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
6//存放头部信息
7 prepareResponse(request, response);
8////将mergedModel中的参数值放到request中
9 renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
10 }
其实就根据ModelAndView和Request中的数据,加载视图,然后写入到Response中(先设置ContentType),最后输出给用户。
微信公众号:宋坤明
更多精彩请参考 完整版系列 请参考此博文 也可以直接关注我
View 渲染的更多相关文章
- ASP.NET没有魔法——ASP.NET MVC Razor与View渲染
对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的界面呈现工作是由浏览器完成的,Web应用的原理是通过Http协议从服务器上获取到 ...
- 把Android原生的View渲染到OpenGL Texture
http://blog.csdn.net/u010949962/article/details/41865777 最近要把Android 原生的View渲染到OpenGL GLSurfaceView中 ...
- ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理
ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...
- Yii2.0源码阅读-视图(View)渲染过程
之前的文章我们根据源码的分析,弄清了Yii如何处理一次请求,以及根据解析的路由如何调用控制器中的action,那接下来好奇的可能就是,我在控制器action中执行了return $this->r ...
- 高级UI晋升之View渲染机制(二)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...
- 在渲染前获取 View 的宽高
在渲染前获取 View 的宽高 这是一个比较有意义的问题,或者说有难度的问题,问题的背景为:有时候我们需要在view渲染前去获取其宽高,典型的情形是,我们想在onCreate.onStart.onRe ...
- MVC Return View() 和 Return PartialView()的区别
分部视图在action中返回一定要用PartialView(),而不要偷懒使用View(),因为,如果你使用View()渲染视图,系统会认为你是一个标准视图,会为你加个默认的母板页(Layout),除 ...
- Qt Model/View(官方翻译,图文并茂)
http://doc.trolltech.com/main-snapshot/model-view-programming.html 介绍 Qt 4推出了一组新的item view类,它们使用mode ...
- android 自定义view详解
1.自定义View前首先要了解一下View的方法,虽然有些不一定要实现. 分类 方法 描述 创建 Constructors View中有两种类型的构造方法,一种是在代码中构建View,另一种是填充布局 ...
随机推荐
- 使用PHP生成二维码支持自定义logo
require_once 'phpqrcode/phpqrcode.php'; //引入类库 $text = "https://www.baidu.com/";//要生成二维码的文 ...
- 服务器远程连接mysql问题解决
一. centos下解决远程连接不上的问题. 1.查看centos 下防火墙是否关闭: 通过进程: ps -aux |grep firewalld ps -ef |grep firewalld 通过服 ...
- 使用Selenium时,如何选择ChromeDriver驱动版本对应Chrome浏览器版本
ChromeDriver版本 支持的Chrome版本 v2.46 v72-74 v2.45 v71-73 v2.44 v70-72 v2.43 v69-71 v2.42 v68-70 v2.41 ...
- 虚拟机内安装Centos7步骤
下面就来看看怎么安装centos7,首先就是要准备一个虚拟机了 简称VM,当然虚拟机的安装步骤,我也不再多说,我用的Workstation 15 Pro的版本,我们直接打开虚拟机,打开界面如下: 在安 ...
- 并查集(模板&典型例题整理)
参考:https://blog.csdn.net/oliver233/article/details/70162173 带路径压缩模板: #include<stdio.h> ]; int ...
- 20155220吴思其 实验2 Windows口令破解
实验目的: 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 实验人数 每组一人 系统环境 windows 实验工具 LC5 SuperDic 实验原理 口令破解方法 ...
- 20155307 2017-2018-3 《Java程序设计》第3周学习总结
20155307 2017-2018-3 <Java程序设计>第3周学习总结 教材学习内容总结 类相当于是设计图,对象是根据类设计出来的.用class定义,名字叫clothes.可以用ne ...
- C# JSON和对象之间互相转换
1.首先是声明用户信息对象,DataContract修饰类,表示可以被解析成JSON,DataMember修饰属性,Order表示 解析的顺序,另外Lover是数组列表,表示女朋友个数 Address ...
- [POJ2104]Kth Number-[整体二分]
Description 传送门 Solution 将所有询问放在一起,二分答案的同时把区间[l,r]内的数按大小分类. Code #include<iostream> #include&l ...
- 北京Uber优步司机奖励政策(4月15日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...