Java-Spring入门指南(二十一)Thymeleaf 视图解析器
- 前言
- 一、Thymeleaf视图解析器
- 二、Thymeleaf视图解析器工作流程
- 三、实战
-
- [3.1 场景1:自定义模板路径(将模板放resources下)](#3.1 场景1:自定义模板路径(将模板放resources下))
- [3.2 场景2:多视图解析器共存(Thymeleaf+JSP)](#3.2 场景2:多视图解析器共存(Thymeleaf+JSP))
- [3.3 问题排查:高频错误与解决方法](#3.3 问题排查:高频错误与解决方法)
前言
- 在上一篇博客中,我们成功搭建了Spring-Thymeleaf环境,通过
springmvc.xml
配置让项目跑通了"Controller返回视图名→渲染HTML页面"的流程。但你可能会疑惑: -
为什么配置里要写三个嵌套的Bean?
ThymeleafViewResolver
、SpringTemplateEngine
、SpringResourceTemplateResolver
之间是什么关系?少了其中一个会怎样? - 这些问题的核心,都指向Thymeleaf的"视图解析器"------它是连接SpringMVC后端(Controller)与前端视图(HTML)的"桥梁",负责处理视图路径拼接、编码转换、模板渲染三大核心任务。如果说Controller是"指挥中心",HTML是"最终页面",那视图解析器就是"运输与组装工人",直接决定页面能否正确找到、正常显示。
- 本文将基于上一篇的
Maven+IDEA+Tomcat 11
环境,从"组件拆解→工作流程→实战配置→问题排查"四个维度,彻底讲透Thymeleaf视图解析器.
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482

thymeleaf官方中文文档地址
https://www.wuzao.com/thymeleaf/documentation.html
上一篇博客地址(Spring-Thymeleaf环境搭建)
https://blog.csdn.net/2402_83322742/article/details/152445618?spm=1001.2014.3001.5501
一、Thymeleaf视图解析器
回顾上一篇的springmvc.xml
配置,Thymeleaf视图解析器并非"单个组件",而是由视图解析器(ViewResolver)、模板引擎(TemplateEngine)、模板解析器(TemplateResolver) 三个组件嵌套组成。这三者各司其职,缺一不可,共同完成视图渲染工作。
先看完整配置代码(复用并标注核心组件):
xml
<!-- 3. Thymeleaf视图解析器(顶层组件:最终返回渲染后的视图) -->
<bean id="viewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="order" value="1"/> <!-- 解析优先级 -->
<property name="characterEncoding" value="UTF-8"/> <!-- 编码控制 -->
<!-- 关联模板引擎(中间层:处理模板逻辑) -->
<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>
1.1 底层:模板解析器(SpringResourceTemplateResolver)
作用:负责"找到HTML模板文件",是整个解析流程的"导航仪"------根据配置的规则,把Controller返回的"视图名"转换成实际的文件路径。
核心配置参数说明
参数名 | 配置值示例 | 作用与注意事项 |
---|---|---|
prefix |
/WEB-INF/templates/ |
视图前缀:指定模板文件的存放目录,必须以/ 结尾。比如前缀是/WEB-INF/templates/ ,视图名是index ,就会拼成/WEB-INF/templates/index |
suffix |
.html |
视图后缀:指定模板文件的扩展名,比如后缀是.html ,上面的路径会最终变成/WEB-INF/templates/index.html |
templateMode |
HTML |
模板模式:指定模板文件的类型,常用值有HTML (普通HTML)、HTML5 (严格HTML5语法)、XML (XML文件);开发HTML页面用HTML 即可 |
characterEncoding |
UTF-8 |
模板编码:设置读取HTML文件时的编码格式,必须与HTML文件本身的编码一致(比如HTML里的<meta charset="UTF-8"> ),否则会出现"HTML静态内容乱码" |
cacheable |
false (开发环境) |
缓存开关:默认true (生产环境推荐),开启后模板文件修改需重启项目;开发环境建议设为false ,修改HTML后刷新页面即可生效,无需重启 |
1.2 中间层:模板引擎(SpringTemplateEngine)
作用 :负责"处理模板逻辑",是解析流程的"加工车间"------接收模板解析器找到的HTML文件,解析其中的th:*
语法(如th:text="${message}"
),把后端传递的动态数据(Model中的数据)嵌入到HTML中,生成"带动态内容的模板"。
核心特点
- 依赖模板解析器:必须通过
templateResolver
属性关联SpringResourceTemplateResolver
,否则无法获取HTML文件。 - 支持Spring特性:相比Thymeleaf原生的
TemplateEngine
,SpringTemplateEngine
能更好地兼容SpringMVC的Model
、RequestContext
等对象,比如直接解析Model
中的数据。 - 无需额外配置:大部分场景下,只要关联了模板解析器,无需添加其他属性(复杂需求如自定义方言可再扩展)。
1.3 顶层:视图解析器(ThymeleafViewResolver)
作用 :负责"返回最终视图",是解析流程的"交付窗口"------接收模板引擎处理后的模板,将其封装成SpringMVC能识别的View
对象,最终响应给浏览器,显示完整页面。
核心配置参数说明
参数名 | 配置值示例 | 作用与注意事项 |
---|---|---|
order |
1 |
解析优先级:当项目中有多个视图解析器(如同时有Thymeleaf和JSP解析器)时,order 值越小,优先级越高;只用水Thymeleaf时,设为1 即可 |
characterEncoding |
UTF-8 |
响应编码:设置向浏览器返回页面时的编码格式,必须与模板解析器的characterEncoding 一致,否则会出现"动态数据乱码"(比如Model中的中文显示为???) |
templateEngine |
关联SpringTemplateEngine |
强制关联:必须通过该属性绑定模板引擎,否则无法获取处理后的动态模板,直接返回404错误 |
二、Thymeleaf视图解析器工作流程
理解了三个组件的作用后,我们结合"用户访问/index
→显示带动态数据的HTML"的场景,拆解完整工作流程,让你清楚每一步的执行逻辑:
-
Controller返回视图名 :用户访问
http://localhost:8080/index
,IndexController
的index
方法执行,返回视图名"index"
,并通过Model
传递message="Hello Thymeleaf!"
。java@RequestMapping("/index") public String index(Model model) { model.addAttribute("message", "Hello Thymeleaf!"); return "index"; // 返回视图名 }
-
模板解析器拼路径 :
SpringResourceTemplateResolver
接收视图名"index"
,结合prefix="/WEB-INF/templates/"
和suffix=".html"
,拼接出模板文件的实际路径:/WEB-INF/templates/index.html
,并读取该HTML文件。 -
模板引擎处理逻辑 :
SpringTemplateEngine
接收模板解析器传递的HTML文件,解析其中的th:*
语法------找到th:text="${message}"
,从Model
中获取message
的值,将HTML中的静态文本"后端数据将在这里显示"替换为"Hello Thymeleaf!",生成"动态模板"。 -
视图解析器返回页面 :
ThymeleafViewResolver
接收模板引擎处理后的"动态模板",封装成View
对象,设置响应编码为UTF-8
,将最终的HTML页面响应给浏览器,用户看到带动态数据的页面。
流程总结 :
Controller返回视图名
→ 模板解析器拼路径找HTML
→ 模板引擎解析th:*语法嵌数据
→ 视图解析器返回最终页面
三、实战
掌握了基础后,我们针对实际开发中高频遇到的场景做扩展配置,并总结"404视图找不到""中文乱码"等问题的排查步骤,帮你避坑。
3.1 场景1:自定义模板路径(将模板放resources下)
上一篇中我们把HTML放在WEB-INF/templates
下,若想将模板文件放在src/main/resources/templates
下(更符合Spring Boot的目录规范,也便于打包),只需修改SpringResourceTemplateResolver
的prefix
和resourceLoaderPath
:
xml
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<!-- 关键:指定资源加载路径为classpath(即resources目录) -->
<property name="resourceLoaderPath" value="classpath:/templates/"/>
<property name="prefix" value=""/> <!-- 此时prefix设为空,因为resourceLoaderPath已包含路径 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="cacheable" value="false"/> <!-- 开发环境关缓存 -->
</bean>
- 注意:
resourceLoaderPath
的值classpath:/templates/
表示"从resources目录下的templates文件夹加载模板",此时prefix
无需再写路径,直接用视图名匹配即可(如视图名index
对应resources/templates/index.html
)。
3.2 场景2:多视图解析器共存(Thymeleaf+JSP)
若老项目需同时支持Thymeleaf和JSP,可配置两个视图解析器,通过order
控制优先级(Thymeleaf优先):
xml
<!-- 1. Thymeleaf视图解析器(order=1,优先级高) -->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<!-- 关联模板引擎...(同之前配置) -->
</property>
</bean>
<!-- 2. JSP视图解析器(order=2,优先级低) -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2"/>
<property name="prefix" value="/WEB-INF/jsp/"/> <!-- JSP文件路径 -->
<property name="suffix" value=".jsp"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
- 执行逻辑:当Controller返回视图名时,先由Thymeleaf解析器查找对应HTML文件;若找不到(如视图名
user
对应/WEB-INF/templates/user.html
不存在),再由JSP解析器查找/WEB-INF/jsp/user.jsp
。
3.3 问题排查:高频错误与解决方法
问题1:404错误(视图找不到)
-
可能原因1:
prefix
路径写错(最常见)。排查:检查
SpringResourceTemplateResolver
的prefix
是否以/
结尾,路径是否与实际HTML存放目录一致。比如HTML在WEB-INF/templates
下,prefix
必须是/WEB-INF/templates/
(少写末尾的/
会拼成/WEB-INF/templatesindex.html
,肯定找不到)。 -
可能原因2:视图名与HTML文件名不一致。
排查:Controller返回的视图名(如
return "index"
)必须与HTML文件名(index.html
)完全一致(大小写敏感,Windows下不敏感,但Linux下敏感,建议统一小写)。 -
可能原因3:资源加载路径错误(模板放resources下时)。
排查:若模板在
resources/templates
下,需配置resourceLoaderPath="classpath:/templates/"
,且prefix
设为空,否则会从WEB-INF
下找文件。
问题2:中文乱码(静态/动态内容乱码)
-
静态内容乱码(HTML里的中文乱码):
排查:检查
SpringResourceTemplateResolver
的characterEncoding
是否为UTF-8
,且HTML文件本身的编码是否为UTF-8(IDEA中右键HTML文件→"File Encoding"→确认"Encoding"为UTF-8)。 -
动态内容乱码(Model中的中文乱码):
排查:检查
ThymeleafViewResolver
的characterEncoding
是否为UTF-8
,且与模板解析器的编码一致;同时确保web.xml
中配置了编码过滤器(若未配置,POST请求传递的中文会乱码):xml<!-- web.xml中添加编码过滤器(建议配置) --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482
|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |
