Java-Spring入门指南(二十一)Thymeleaf 视图解析器

Java-Spring入门指南(二十一)Thymeleaf 视图解析器


前言

  • 在上一篇博客中,我们成功搭建了Spring-Thymeleaf环境,通过springmvc.xml配置让项目跑通了"Controller返回视图名→渲染HTML页面"的流程。但你可能会疑惑:
  • 为什么配置里要写三个嵌套的Bean? ThymeleafViewResolverSpringTemplateEngineSpringResourceTemplateResolver之间是什么关系?少了其中一个会怎样?

  • 这些问题的核心,都指向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原生的TemplateEngineSpringTemplateEngine能更好地兼容SpringMVC的ModelRequestContext等对象,比如直接解析Model中的数据。
  • 无需额外配置:大部分场景下,只要关联了模板解析器,无需添加其他属性(复杂需求如自定义方言可再扩展)。

1.3 顶层:视图解析器(ThymeleafViewResolver)

作用 :负责"返回最终视图",是解析流程的"交付窗口"------接收模板引擎处理后的模板,将其封装成SpringMVC能识别的View对象,最终响应给浏览器,显示完整页面。

核心配置参数说明

参数名 配置值示例 作用与注意事项
order 1 解析优先级:当项目中有多个视图解析器(如同时有Thymeleaf和JSP解析器)时,order值越小,优先级越高;只用水Thymeleaf时,设为1即可
characterEncoding UTF-8 响应编码:设置向浏览器返回页面时的编码格式,必须与模板解析器的characterEncoding一致,否则会出现"动态数据乱码"(比如Model中的中文显示为???)
templateEngine 关联SpringTemplateEngine 强制关联:必须通过该属性绑定模板引擎,否则无法获取处理后的动态模板,直接返回404错误

二、Thymeleaf视图解析器工作流程

理解了三个组件的作用后,我们结合"用户访问/index→显示带动态数据的HTML"的场景,拆解完整工作流程,让你清楚每一步的执行逻辑:

  1. Controller返回视图名 :用户访问http://localhost:8080/indexIndexControllerindex方法执行,返回视图名"index",并通过Model传递message="Hello Thymeleaf!"

    java 复制代码
    @RequestMapping("/index")
    public String index(Model model) {
        model.addAttribute("message", "Hello Thymeleaf!");
        return "index"; // 返回视图名
    }
  2. 模板解析器拼路径SpringResourceTemplateResolver接收视图名"index",结合prefix="/WEB-INF/templates/"suffix=".html",拼接出模板文件的实际路径:/WEB-INF/templates/index.html,并读取该HTML文件。

  3. 模板引擎处理逻辑SpringTemplateEngine接收模板解析器传递的HTML文件,解析其中的th:*语法------找到th:text="${message}",从Model中获取message的值,将HTML中的静态文本"后端数据将在这里显示"替换为"Hello Thymeleaf!",生成"动态模板"。

  4. 视图解析器返回页面ThymeleafViewResolver接收模板引擎处理后的"动态模板",封装成View对象,设置响应编码为UTF-8,将最终的HTML页面响应给浏览器,用户看到带动态数据的页面。

流程总结
Controller返回视图名模板解析器拼路径找HTML模板引擎解析th:*语法嵌数据视图解析器返回最终页面

三、实战

掌握了基础后,我们针对实际开发中高频遇到的场景做扩展配置,并总结"404视图找不到""中文乱码"等问题的排查步骤,帮你避坑。

3.1 场景1:自定义模板路径(将模板放resources下)

上一篇中我们把HTML放在WEB-INF/templates下,若想将模板文件放在src/main/resources/templates下(更符合Spring Boot的目录规范,也便于打包),只需修改SpringResourceTemplateResolverprefixresourceLoaderPath

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路径写错(最常见)。

    排查:检查SpringResourceTemplateResolverprefix是否以/结尾,路径是否与实际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里的中文乱码):

    排查:检查SpringResourceTemplateResolvercharacterEncoding是否为UTF-8,且HTML文件本身的编码是否为UTF-8(IDEA中右键HTML文件→"File Encoding"→确认"Encoding"为UTF-8)。

  • 动态内容乱码(Model中的中文乱码):

    排查:检查ThymeleafViewResolvercharacterEncoding是否为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

|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |

相关推荐
Predestination王瀞潞3 小时前
类的多态(Num020)
开发语言·c++
Predestination王瀞潞3 小时前
类的继承(Num019)
开发语言·c++
源码集结号3 小时前
一套智慧工地云平台源码,支持监管端、项目管理端,Java+Spring Cloud +UniApp +MySql技术开发
java·mysql·spring cloud·uni-app·源码·智慧工地·成品系统
EnCi Zheng3 小时前
Spring Security 最简配置完全指南-从入门到精通前后端分离安全配置
java·安全·spring
程序员小假3 小时前
为什么这些 SQL 语句逻辑相同,性能却差异巨大?
java·后端
万粉变现经纪人3 小时前
如何解决 pip install -r requirements.txt 无效可编辑项 ‘e .‘(-e 拼写错误)问题
开发语言·python·r语言·beautifulsoup·pandas·pip·scipy
say_fall3 小时前
精通C语言(2.结构体)(内含彩虹)
c语言·开发语言·windows
潇凝子潇3 小时前
在使用Nacos作为注册中心和配置中心时,如何解决服务发现延迟或配置更新不及时的问题
开发语言·python·服务发现
泉城老铁4 小时前
springboot实现对接poi 导出excel折线图
java·spring boot·后端