【SpringMVC笔记】 - 5 - View
一、视图 View 概述
在 SpringMVC 中,视图(View) 负责将控制器处理后的模型数据渲染为客户端可识别的格式(如 HTML、PDF、Excel 等)并响应输出,是 MVC 模式中视图层的核心载体。
SpringMVC 的视图设计遵循开闭原则(OCP),视图与框架底层解耦合,支持通过配置灵活切换、扩展视图技术,无需修改框架源码,扩展性极强。
二、SpringMVC 支持的常见视图类型
SpringMVC 内置 + 第三方整合,支持丰富的视图实现,常用类型如下:
- InternalResourceView
- SpringMVC 内置视图,专为 JSP 模板设计,对应内部资源视图解析器。
- 负责服务器内部转发、JSP 页面渲染。
- RedirectView
- SpringMVC 内置视图,专门实现重定向功能,对应重定向跳转。
- ThymeleafView
- 第三方视图,适配 Thymeleaf 模板引擎,现代化 Web 开发主流选择。
- FreeMarkerView
- 第三方视图,适配 FreeMarker 模板引擎。
- VelocityView
- 第三方视图,适配 Velocity 模板引擎(使用较少)。
- PDFView/ExcelView
- 第三方扩展视图,专门用于生成 PDF、Excel 文件响应。
三、视图机制核心类与接口
SpringMVC 视图渲染全程由四大核心组件协同完成,职责清晰、分工明确:
1. DispatcherServlet(前端控制器)
- 地位:整个 SpringMVC 的中央调度器,所有请求入口。
- 核心职责:接收请求 → 分发到 Controller → 接收返回值 → 调用视图解析器 → 触发视图渲染。
- 核心方法:
doDispatch()(请求处理总入口)。
2. ViewResolver 接口(视图解析器)
- 地位:逻辑视图 → 物理视图的转换器。
- 核心职责:
- 接收 Controller 返回的逻辑视图名(如 index、test)。
- 拼接前缀、后缀,转换为物理视图路径(如 /WEB-INF/templates/index.html)。
- 创建并返回对应 View 接口实现类对象。
- 核心方法:
resolveViewName(String viewName, Locale locale)。 - 常用实现:
- ThymeleafViewResolver(Thymeleaf 专用)
- InternalResourceViewResolver(JSP 专用)
3. View 接口(视图)
- 地位:最终渲染执行者。
- 核心职责:将模型数据(Model)与模板结合,渲染为 HTML / 文件等格式,响应给浏览器。
- 核心方法:
render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)。 - 常用实现:ThymeleafView、InternalResourceView、RedirectView。
4. ViewResolverRegistry(视图解析器注册器)
- 职责:Web 容器启动时,注册所有视图解析器,按
order值排序存入 List,优先级数字越小越先执行。
四、视图渲染完整执行原理(以 Thymeleaf 为例)
结合项目真实代码流程,完整执行步骤:
- 浏览器发送请求(如
/或/a)到服务器。 - DispatcherServlet 接收请求,匹配映射找到对应 Controller。
- 执行 Controller 方法(如
index()、toA()),返回逻辑视图名(如 index、forward:/b、redirect:/b)。 - DispatcherServlet 调用 ViewResolver(本项目为 ThymeleafViewResolver)。
- 视图解析器拼接前缀 + 逻辑视图名 + 后缀 ,得到物理视图路径,创建 ThymeleafView 对象。
- DispatcherServlet 调用 View.render() 方法。
- Thymeleaf 引擎解析模板语法,渲染为标准 HTML,响应给浏览器完成展示。
JSP 视图流程完全一致,仅替换为:InternalResourceViewResolver → InternalResourceView。
五、逻辑视图名 → 物理视图名 转换规则
视图解析器通过前缀(prefix) + 逻辑视图名 + 后缀(suffix) 完成映射,是页面跳转的核心规则。
1. Thymeleaf 视图解析器配置(项目真实配置)
xml
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="order" value="1"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
2. 映射示例
- Controller 返回:
return "index"; - 物理路径:
/WEB-INF/templates/index.html - Controller 返回:
return "test"; - 物理路径:
/WEB-INF/templates/test.html
3. JSP 视图解析器对比
xml
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
- 返回
index→/WEB-INF/jsp/index.jsp
六、转发(forward)与 重定向(redirect)
SpringMVC 对原生 Servlet 转发 / 重定向做了封装,使用更简洁,底层原理不变。
1. 核心区别(必记)
| 特性 | 转发 forward | 重定向 redirect |
|---|---|---|
| 请求次数 | 1 次请求 | 2 次请求 |
| 地址栏 | 地址不改变 | 地址会改变 |
| 跨域 | 不支持 | 支持 |
| 访问 WEB-INF | 可以访问 | 不可访问 |
| 数据共享 | 同 request,可共享 | 不同 request,不可直接共享 |
| 底层视图 | InternalResourceView | RedirectView |
2. SpringMVC 代码实现(项目真实代码)
(1)转发:return "forward:/ 目标路径"
- 作用:服务器内部跳转,路径指向另一个 Controller 映射。
- 示例:
java
@Controller
public class ForwardController {
@RequestMapping("/a")
public String toA(){
// 转发到 /b 映射
return "forward:/b";
}
@RequestMapping("/b")
public String toB(){
return "b"; // 指向 b.html
}
}
- 访问
/a→ 地址栏保持/a→ 展示 Page B!!! - 底层原理:使用
InternalResourceView,服务器内部跳转,不经过浏览器重新请求。
(2)重定向:return "redirect:/ 目标路径"
- 作用:告诉浏览器重新发送请求,实现跳转。
- 示例:
java
@Controller
public class ForwardController {
@RequestMapping("/a")
public String toA(){
// 重定向到 /b 映射
return "redirect:/b";
}
@RequestMapping("/b")
public String toB(){
return "b";
}
}
- 访问
/a→ 地址栏变为/b→ 展示 Page B!!! - 底层原理:使用
RedirectView,服务器返回 3xx 状态码,浏览器重新发起请求。
(3)跨域重定向
java
@RequestMapping("/a")
public String toA(){
return "redirect:http://localhost:8080/其他项目/目标路径";
}
七、视图快捷配置:mvc:view-controller
1. 作用
无业务逻辑仅页面跳转时,可省略 Controller,直接在配置文件绑定 URL → 视图,简化代码。
2. 项目真实配置
xml
<!-- 访问 /test → 直接跳转到 test 视图(test.html) -->
<mvc:view-controller path="/test" view-name="test"/>
3. 关键注意点
- 一旦使用
<mvc:view-controller>,必须开启注解驱动,否则所有 Controller 注解失效,访问报 404。 - 开启注解驱动:
xml
<mvc:annotation-driven/>
八、静态资源访问处理
1. 问题原因
DispatcherServlet 拦截 "/",会拦截所有请求(包括 css、js、img 等静态资源),导致静态资源 404。
2. 解决方案(项目采用方案二)
方案一:默认 Servlet 处理(简单)
xml
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
- 原理:DispatcherServlet 找不到资源时,交给 Tomcat 内置 DefaultServlet 处理。
方案二:mvc:resources 精准映射(推荐)
xml
<mvc:annotation-driven/>
<!-- 以 /static/ 开头的请求,去项目 /static/ 目录找资源 -->
<mvc:resources mapping="/static/**" location="/static/"/>
- 示例:
/static/actor.css→ 直接访问项目 static 目录下的 css 文件。 - 优点:精准控制、性能更高、便于管理。
九、自定义视图(扩展)
若需实现自定义视图(如自定义报表、特殊格式输出),只需两步:
- 编写类 实现 View 接口 ,重写
render()方法,完成自定义渲染。 - 编写类 实现 ViewResolver 接口 ,重写
resolveViewName()方法,返回自定义 View 对象。 - 将自定义视图解析器注册到 Spring 容器,配置
order优先级。
SpringMVC 会自动识别并使用自定义视图,完全符合开闭原则。
十、本章核心总结
- SpringMVC 视图层核心:ViewResolver(解析)+ View(渲染)。
- 主流视图:ThymeleafView (现代)、InternalResourceView (JSP)、RedirectView(重定向)。
- 跳转方式:
- 转发:
forward:/路径,一次请求,地址不变,可访问 WEB-INF。 - 重定向:
redirect:/路径,两次请求,地址改变,不可访问 WEB-INF。
- 转发:
- 简化配置:
<mvc:view-controller>替代无业务 Controller。 - 静态资源:用
<mvc:resources>或<mvc:default-servlet-handler>解决 404。 - 设计思想:低耦合、易扩展、符合开闭原则。