视图解析

Spring MVC 定义了 ViewResolverView 接口,它们允许你在浏览器中渲染模型,而无需将你绑定到特定的视图技术。 ViewResolver 提供视图名称和实际视图之间的映射。 View 在移交给特定视图技术之前处理数据准备。

下表提供了有关 ViewResolver 层次结构的更多详细信息

表 1. ViewResolver 实现
ViewResolver 说明

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 头部解析视图。请参阅 内容协商

BeanNameViewResolver

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

处理

你可以通过声明多个解析器 bean 来链接视图解析器,并在必要时通过设置 order 属性来指定顺序。请记住,order 属性越高,视图解析器在链中的位置就越靠后。

ViewResolver 的契约规定,它可以返回 null 来指示找不到视图。但是,对于 JSP 和 InternalResourceViewResolver,找出 JSP 是否存在的方法是通过 RequestDispatcher 执行分派。因此,你必须始终将 InternalResourceViewResolver 配置为视图解析器的总体顺序中的最后一个。

配置视图解析就像向你的 Spring 配置中添加 ViewResolver bean 一样简单。MVC 配置视图解析器 提供了一个专门的配置 API,并用于添加无逻辑的 视图控制器,这些控制器对于在没有控制器逻辑的情况下呈现 HTML 模板很有用。

重定向

视图名称中的特殊redirect:前缀可用于执行重定向。UrlBasedViewResolver(及其子类)将其识别为需要重定向的指令。视图名称的其余部分是重定向 URL。

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

转发

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

内容协商

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

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

有关配置详细信息,请参阅MVC 配置下的视图解析器