Spring教程:ViewResolver 视图解析器以及视图View详解,自定义视图解析器

本教程源码地址
https://gitee.com/blueboz/spring-learn.git

Spring框架中。视图解析器是MVC 的V(视图)环节。这个环节在Spring 中的最主要体现在与如何将模型数据与视图进行绑定渲染?

切入点追踪Controller

首先我们从最简单的控制器开始,如下是我们的控制器代码

这里写图片描述
这个控制器返回了一个userinfo的viewname,以及一些模型对象。

DispatcherServlet

此时,透过了多层的反射返回,来到DispatcherServlet的如下代码
这里写图片描述
Spring 版本务必保持一致,本人的版本是官网的5.x版本。

render送入的是ModelAndVIew对象,以及request,response,这里我们想一个问题。
我们需要渲染一个节目,viewname视图名称有了,模型数据有了。那么剩下的还有什么?没错,剩下的就是怎么去根据这个viewname,找到这个视图。并且按照这个视图的规则,把模型渲染进这个视图。并且将视图转成Stream(流),flush (刷入)到response(响应对象)。
用下面一张图来看看
这里写图片描述

接着我们进入DispatcherServlet中的render方法,查看其具体的逻辑

如图所示
这里写图片描述
可以看到,首先会看看,我们在返回的模型中是否已经有了viewname,如果有viewname,用这个viewname去解析得到View对象。
如果没有,再看看,返回的模型是否已经有了view对象。都没有则报错。
到这里,我们的代码还没有设计到视图解析器。

下面需要我们考虑一点,视图解析器,什么是视图解析器?

ViewResolver视图解析器接口,是一个顶级接口。其只有一个方法。resolveViewName方法,这个方法的作用是根据一个逻辑的视图名称,获取到这个名称应该使用的View对象。View对象是有什么用,view有一个render方法,

@Nullable
View resolveViewName(String viewName, Locale locale) throws Exception;

这里写图片描述

到这里,也许你会有疑问,这个视图解析器与View 到底有什么用?为什么需要这么复杂的搞一个视图解析器跟一个视图。

ViewResolver

这里我说下,视图解析器。就是根据提供的视图名称,内部去实例化一个View子类对象。并返回给dispatcherServlet.

View

而View对象的render方法,则是最终的调动渲染视图方法。会把视图内容刷到响应流中。从而响应到客户端。

我们直接在DispatcherServlet中,根据userinfo找到/WEB-INF/page/userinfo.jsp
并且把modelAndView中的model渲染到jsp界面去,直接返回不就行了吗?
道理是对的,这里的实现方法也是这样的。但是作为框架,一定得考虑到其扩展性,Spring在设计的时候,考虑到扩展性。例如我们需要渲染freeMarker视图,tile视图?pdf视图,以及xls…等等一些列的视图应该怎么办?

哈哈。所以在这里就会出现问题,假如不这样子做,我们是很难去进行扩展我们自己的视图。

那么好,我们接着跟踪。源代码,上面是到了render方法了,下面我们看,render方法到底做了什么,render方法进入resolveViewName方法。
这里写图片描述
在这个方法,首先会判断viewResolvers列表是不是空的,如果不是空的。会遍历所有的viewResolver,并且调动viewResolver中的resolverViewName方法,一旦有一个能解析成功,则马上返回。

这里一般情况下我们都是注入InternalResourceViewResolver
类似下面这个,分别是java代码与xml代码配置两种方式。

InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/page/");
resolver.setSuffix(".jsp");
<bean id="jsp"  class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
  <property name="order" value="44" />
  <property name="contentType" value="text/html"/>
  <property name="prefix" value="/WEB-INF/"/>
  <property name="suffix" value=".jsp"/>
 </bean>

那么我们来看看这个InternalResourceViewResolver到底做了什么,有什么作用。

InternalResourceViewResolver

这里写图片描述

在使用InternalResourceViewResolver需要设置prefix与suffix,其实是在设置urlBaseViewResolver,InternalResourceViewResolver只是把viewclass设置成JstlView而已。

UrlBasedViewResolver

这里写图片描述

这里写图片描述

总之,ViewResolver是根据视图名称获取这个视图的渲染View。并且有这个View全权渲染

猜你喜欢

转载自blog.csdn.net/blueboz/article/details/81840593