View Resolution

Spring MVC定义了`ViewResolver`和`View`接口,可让你在浏览器中呈现模型,而无需限制到特定的视图技术。`ViewResolver`提供视图名称和实际视图之间的映射。`View`解决在移交到特定视图技术之前对数据进行准备的问题。 下表提供了`ViewResolver`层次结构的更多详细信息:

Table 1. ViewResolver implementations
ViewResolver Description

AbstractCachingViewResolver

AbstractCachingViewResolver 的子类缓存他们解析的视图实例。缓存可改善某些视图技术的性能。你可以通过将 cache 属性设置成 false 来关闭缓存。另外,如果你必须在运行时刷新某个视图(例如,当 FreeMarker 模板被修改时),你可以使用 removeFromCache(String viewName, Locale loc) 方法。

UrlBasedViewResolver

ViewResolver 接口的简单实现,该接口生成逻辑视图名称到 URL 的直接解析,不需要显式的映射定义。如果你的逻辑名称以一种直接的方式与你的视图资源名称相匹配,并且不需要任意映射的话,这是一种合适的方式。

InternalResourceViewResolver

UrlBasedViewResolver`的便捷子类,它支持 `InternalResourceView(实际上是 Servlet 和 JSP)和子类,例如 JstlView。您可以使用 setViewClass(..)`为由此解析器生成的全部视图指定试图类。有关详细信息,请参见 `UrlBasedViewResolver javadoc。

FreeMarkerViewResolver

UrlBasedViewResolver 的子类,支持 FreeMarkerView 和它们的自定义子类。

ContentNegotiatingViewResolver

`ViewResolver`接口的实现,它根据请求文件名或 `Accept`报头解析视图。参见 Content Negotiation

BeanNameViewResolver

ViewResolver 接口的实现,它将视图名称解释为当前应用程序上下文中中的 bean 名称。这是一个非常灵活的变量,允许基于不同的视图名称混合和匹配不同的视图类型。每个此类 View 均可定义为 bean,例如在 XML 或配置类中。

Handling

你可以通过声明多个解析器 Bean 来链接视图解析器,如需,可以通过设置`order`属性来指定排序。请记住,排序属性的值越高,视图解析器在链中的位置就越靠后。

ViewResolver 的契约规定,它可以返回 null 以表明无法找到视图。但是,对于 JSP 和 InternalResourceViewResolver,找出 JSP 是否存在的唯一方法是通过`RequestDispatcher`执行调度。因此,你必须始终将`InternalResourceViewResolver`配置为视图解析器的整体顺序中的最后一个。

配置视图解析与向您的 Spring 配置添加 ViewResolver Bean 一样简单。MVC ConfigView Resolvers 提供了一个专门的配置 API,并用于添加无逻辑 View Controllers,它们对于在没有控制器逻辑的情况下进行 HTML 模板渲染非常有用。

Redirecting

视图名称中的特殊`redirect:`前缀使你可以执行重定向。UrlBasedViewResolver(及其子类)将这识别为需要重定向的说明。视图名称的其余部分是重定向 URL。

其最终效果与控制器已返回`RedirectView`相同,但现在控制器本身可以根据逻辑视图名称进行操作。逻辑视图名称(比如`redirect:/myapp/some/resource`)相对于当前 Servlet 上下文重定向,而`redirect:https://myhost.com/some/arbitrary/path`这样的名称则重定向到绝对 URL。

Forwarding

还可以对最终由`UrlBasedViewResolver`及其子类解析的视图名称使用特殊的`forward:`前缀。这会创建一个`InternalResourceView`,该视图会执行`RequestDispatcher.forward()。因此,此前缀对`InternalResourceViewResolver`和`InternalResourceView(对于 JSP)无用,但如果你使用其他视图技术但仍想强制转发资源以供 Servlet/JSP 引擎处理,它可能会有所帮助。请注意,你也可以链接多个视图解析器。

Content Negotiation

ContentNegotiatingViewResolver 自身不会解析视图,而是将任务委托给其他视图解析器并选择与客户端请求的表示相似的视图。表示可以从 Accept 头部或查询参数(例如 "/path?format=pdf")中确定。

ContentNegotiatingViewResolver`通过将请求媒体类型与与其各个`ViewResolver`关联的`View`支持的媒体类型(也称为`Content-Type)进行比较来选择适合处理请求的`View`。列表中第一个具有兼容`Content-Type`的`View`向客户端返回表示。如果`ViewResolver`链无法提供兼容的视图,则咨询通过`DefaultViews`属性指定的视图列表。后一种选择适用于独立`View`,这些`View`可以呈现当前资源的适当表示,无论逻辑视图名称如何。Accept`标头可以包含通配符(例如`text/*),在这种情况下,`Content-Type`为`text/xml`的`View`是兼容匹配项。

有关配置详细信息,请参见 MVC Config 下的 View Resolvers