Skip to content

视图解析 (View Resolution)

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

ViewResolver 实现

以下是常用的 ViewResolver 实现:

ViewResolver说明
InternalResourceViewResolver最常用。用于解析 JSP 和 Servlet 资源。建议将其放在解析器链的最后。
FreeMarkerViewResolver支持 FreeMarker 模板引擎。
BeanNameViewResolver将视图名解释为 Spring 容器中的 Bean 名称。非常灵活。
ContentNegotiatingViewResolver根据请求的文件扩展名或 Accept 头自动选择最合适的视图(内容协商)。
UrlBasedViewResolver简单的实现,将逻辑名直接映射到 URL,无需显式映射定义。

解析处理 (Handling)

你可以通过声明多个 ViewResolver Bean 来形成解析器链,并设置 order 属性来指定顺序。order 值越大,解析器在链中的位置越靠后。

注意

对于 JSP 和 InternalResourceViewResolver,唯一确定 JSP 是否存在的方法是通过 RequestDispatcher 进行转发。因此,你必须始终将 InternalResourceViewResolver 放在解析器链的最后

特殊前缀:重定向与转发

在视图逻辑名中使用特殊前缀可以实现特定的跳转行为:

  • redirect::执行重定向。例如 return "redirect:/index"。它会相对于当前的 Servlet 上下文进行重定向。
  • forward::执行内部转发。这会创建一个 InternalResourceView 并调用 RequestDispatcher.forward()

内容协商 (Content Negotiation)

ContentNegotiatingViewResolver 自己并不解析视图,而是委托给其他解析器,并选择一个与客户端请求的表示形式(通过 Accept 头或查询参数如 ?format=json)最接近的视图。


补充教学

1. 为什么 RESTful 应用中很少看到 ViewResolver?

在现代的 REST 架构中,由于我们通常通过 @ResponseBody@RestController 返回 JSON 数据,Spring MVC 会直接使用 HttpMessageConverter 而不是 ViewResolver

  • ViewResolver 场景:多见于传统的 SSR(服务端渲染)项目,如使用 Thymeleaf、JSP 或 FreeMarker。

2. redirect: vs 外部完整 URL

  • return "redirect:/home":重定向到当前站点的 /home。Spring 会自动帮你处理 Context Path(上下文路径)。
  • return "redirect:https://google.com":重定向到外部站点。Spring 发现是完整协议头,就不会拼接本地路径。

3. 如何解决 404 跳转逻辑?

如果你使用了 InternalResourceViewResolver,由于它总是认为自己能处理视图(即使 JSP 不存在),这会导致容器最后才报 404。 最佳实践:在 Spring Boot 中,推荐使用 @ControllerAdvice 结合 NoHandlerFoundException 捕获异常,或者通过容器的错误页面配置(如我们在“异常处理”章节所讲)来统一处理 404 逻辑。

Based on Spring Framework.