- 视图解析器的作用
-
- 根据返回的逻辑视图找到对应的物理视图,并且将其封装成一个View对象,由视图渲染器进行视图的渲染最终展现给用户
-
- ViewResolver 接口
-
- 根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称 将其解析成 View,View 是用来渲染页面的,也就是将 Model 填入模板中,生成 html 或 其他格式的文件。
-
- 接口内的抽象方法
@Nullable
View resolveViewName(String viewName, Locale locale) throws Exception;//返回view对象
- 一)AbstractCachingViewResolver 抽象类
-
- AbstractCachingViewResolver 是带有缓存的 ViewResolver,它每次解析时先从缓存里查 找,如果找到视图就返回,没有就创建新的视图,且创建新视图的方法由其子类实现
- 每次进行视图解析的时候都会先判断使用的视图解析器是否支持缓存
-
@Override
@Nullable
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (!isCache()) {//是否支持缓存
return createView(viewName, locale);/
}
else {
Object cacheKey = getCacheKey(viewName, locale);//创建一个的缓存的key
View view = this.viewAccessCache.get(cacheKey);//在缓存区内混去一个view确定当前的key可用
if (view == null) {
synchronized (this.viewCreationCache) {
view = this.viewCreationCache.get(cacheKey);//在缓存的map中获取
if (view == null) {
// Ask the subclass to create the View object.
view = createView(viewName, locale);//创建view视图
if (view == null && this.cacheUnresolved) {
view = UNRESOLVED_VIEW;
}
if (view != null) {
this.viewAccessCache.put(cacheKey, view);//添加缓存
this.viewCreationCache.put(cacheKey, view);//添加缓存
}
}
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace(formatKey(cacheKey) + "served from cache");
}
}
return (view != UNRESOLVED_VIEW ? view : null);
}
}
- createView方法最终调用的是实现类的方法
@Nullable
protected View createView(String viewName, Locale locale) throws Exception {
return loadView(viewName, locale);//为子类实现的方法创建一个view对象
}
- 1)XmlViewResolver视图解析器
-
- 该解析器是根据xml文件进行视图解析的,并且次视图的解析器不包含渲染器,在声明的时候需要添加渲染器
- 配置如下
-
- loadView
@Override
protected View loadView(String viewName, Locale locale) throws BeansException {
BeanFactory factory = initFactory();//初始化工厂
try {
return factory.getBean(viewName, View.class);//使用工程宇航创建View对象
}
catch (NoSuchBeanDefinitionException ex) {
// Allow for ViewResolver chaining...
return null;
}
}
- ResourceBundleViewResolver解析器
-
- 使用java资源文件进行视图的解析,同样也不支持视图渲染器,需要指定渲染器
- 配置如下
- (class)是必须要有的
- url也是必须要有的,前缀可以是随意
- JstlView是视图渲染器支持Jstl标签的
-
- 源码
@Override
protected View loadView(String viewName, Locale locale) throws Exception {
BeanFactory factory = initFactory(locale);//使用
try {
return factory.getBean(viewName, View.class);
}
catch (NoSuchBeanDefinitionException ex) {
// Allow for ViewResolver chaining...
return null;
}
}
- UrlBasedViewResolver解析器
- UrlBasedViewResolver 提供了拼接 URL 的方式来解析视图,通过 prefix 属性拼接一 个前缀,通过 suffix 属性拼接一个后缀,就得到了视图的 URL。还可以加入 redirect: 与 forword: 前缀,使用 redirect: 前缀会调用 HttpServletResponse 对象的 sendRedirect() 方法 进行重定向,使用 forword: 前缀会利用 RequestDispatcher 的 forword 方式跳转到指定的地 址。另外,使用时还要指定 viewClass 属性,表示要解析成哪种 View
-
- 此类本身不支持视图解析,在进行配置的时候需要指定视图解析器
- viewClass
-
- 在进行配置的时候需要指定的解析器
@Override
protected View loadView(String viewName, Locale locale) throws Exception {
AbstractUrlBasedView view = buildView(viewName);
View result = applyLifecycleMethods(viewName, view);
return (view.checkResource(locale) ? result : null);
}
- InternalResourceViewResolver 类
- InternalResourceViewResolver 是 UrlBasedViewResolver 的 子 类 , 将 InternalResourceView 作为默认的 View 类,但如果当前 classpath 中有 jstl 的 jar 包时则 使用 JstlView 作为 view 来渲染。
- UrlBasedViewResolver 和
-
- UrlBasedViewResolver 类InternalResourceViewResolver 类之间最大区别就是父类没有内嵌视图渲染器,而子类已经渲染视图的渲染器
-
- InternalResourceViewResolver 类
- 总结
-
- 1.视图解析器只要分为四种,并且支持很多的形式的视图如jsp、json等
- 2.大多数的解析器没有内嵌视图渲染器
- 3.默认的使用的渲染器是InternalResoutceViewResolver
-