【SpringMVC笔记】 - 5 - View

【SpringMVC笔记】 - 5 - View

一、视图 View 概述

在 SpringMVC 中,视图(View) 负责将控制器处理后的模型数据渲染为客户端可识别的格式(如 HTML、PDF、Excel 等)并响应输出,是 MVC 模式中视图层的核心载体。

SpringMVC 的视图设计遵循开闭原则(OCP),视图与框架底层解耦合,支持通过配置灵活切换、扩展视图技术,无需修改框架源码,扩展性极强。


二、SpringMVC 支持的常见视图类型

SpringMVC 内置 + 第三方整合,支持丰富的视图实现,常用类型如下:

  1. InternalResourceView
    • SpringMVC 内置视图,专为 JSP 模板设计,对应内部资源视图解析器。
    • 负责服务器内部转发、JSP 页面渲染。
  2. RedirectView
    • SpringMVC 内置视图,专门实现重定向功能,对应重定向跳转。
  3. ThymeleafView
    • 第三方视图,适配 Thymeleaf 模板引擎,现代化 Web 开发主流选择。
  4. FreeMarkerView
    • 第三方视图,适配 FreeMarker 模板引擎。
  5. VelocityView
    • 第三方视图,适配 Velocity 模板引擎(使用较少)。
  6. PDFView/ExcelView
    • 第三方扩展视图,专门用于生成 PDF、Excel 文件响应。

三、视图机制核心类与接口

SpringMVC 视图渲染全程由四大核心组件协同完成,职责清晰、分工明确:

1. DispatcherServlet(前端控制器)

  • 地位:整个 SpringMVC 的中央调度器,所有请求入口。
  • 核心职责:接收请求 → 分发到 Controller → 接收返回值 → 调用视图解析器 → 触发视图渲染。
  • 核心方法:doDispatch()(请求处理总入口)。

2. ViewResolver 接口(视图解析器)

  • 地位:逻辑视图 → 物理视图的转换器。
  • 核心职责:
    1. 接收 Controller 返回的逻辑视图名(如 index、test)。
    2. 拼接前缀、后缀,转换为物理视图路径(如 /WEB-INF/templates/index.html)。
    3. 创建并返回对应 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 为例)

结合项目真实代码流程,完整执行步骤:

  1. 浏览器发送请求(如 //a)到服务器。
  2. DispatcherServlet 接收请求,匹配映射找到对应 Controller。
  3. 执行 Controller 方法(如 index()toA()),返回逻辑视图名(如 index、forward:/b、redirect:/b)。
  4. DispatcherServlet 调用 ViewResolver(本项目为 ThymeleafViewResolver)。
  5. 视图解析器拼接前缀 + 逻辑视图名 + 后缀 ,得到物理视图路径,创建 ThymeleafView 对象。
  6. DispatcherServlet 调用 View.render() 方法。
  7. 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 文件。
  • 优点:精准控制、性能更高、便于管理。

九、自定义视图(扩展)

若需实现自定义视图(如自定义报表、特殊格式输出),只需两步:

  1. 编写类 实现 View 接口 ,重写 render() 方法,完成自定义渲染。
  2. 编写类 实现 ViewResolver 接口 ,重写 resolveViewName() 方法,返回自定义 View 对象。
  3. 将自定义视图解析器注册到 Spring 容器,配置 order 优先级。

SpringMVC 会自动识别并使用自定义视图,完全符合开闭原则。


十、本章核心总结

  1. SpringMVC 视图层核心:ViewResolver(解析)+ View(渲染)
  2. 主流视图:ThymeleafView (现代)、InternalResourceView (JSP)、RedirectView(重定向)。
  3. 跳转方式:
    • 转发:forward:/路径,一次请求,地址不变,可访问 WEB-INF。
    • 重定向:redirect:/路径,两次请求,地址改变,不可访问 WEB-INF。
  4. 简化配置:<mvc:view-controller> 替代无业务 Controller。
  5. 静态资源:用 <mvc:resources><mvc:default-servlet-handler> 解决 404。
  6. 设计思想:低耦合、易扩展、符合开闭原则
相关推荐
毅炼1 小时前
MyBatis 常见问题总结
java·数据库·sql·mybatis
代数狂人1 小时前
空天母舰作战模拟系统 IntelliJ IDEA Ultimate 官方1年100%折扣码赠送
intellij-idea
清心歌1 小时前
LinkedList 深入解析
java
GDAL1 小时前
IntelliJ IDEA常用快捷键
ide·intellij-idea
鱼鳞_1 小时前
Java学习笔记_Day32(IO流字符集字符流)
java·笔记·学习
Rsun045511 小时前
17、Java 责任链模式从入门到实战
java·python·责任链模式
GDAL1 小时前
IntelliJ IDEA 前端开发全面教程
java·ide·intellij-idea
rabbit_pro1 小时前
IDEA保存SSH会话信息
java·ssh·intellij-idea
Rsun045511 小时前
12、Java 享元模式从入门到实战
java·开发语言·享元模式