1. SpringBoot3与Thymeleaf的完美组合SpringBoot3作为当前Java生态中最流行的开发框架与Thymeleaf模板引擎的结合堪称Web开发的黄金搭档。我最近在一个电商后台管理系统的项目中就采用了这个技术组合实测下来开发效率提升了至少40%。Thymeleaf最大的优势在于它的自然模板特性。简单来说你写的HTML文件可以直接在浏览器中打开预览不需要启动服务端。当与SpringBoot3集成后这些静态HTML又能自动变成动态页面。这种开发体验对于前端和后端开发者来说都极其友好。在实际项目中我发现Thymeleaf特别适合以下场景需要快速开发的管理后台系统对SEO有要求的营销页面需要与SpringSecurity深度集成的系统多语言国际化的企业级应用2. 项目初始化与基础配置2.1 创建SpringBoot3项目首先用Spring Initializr创建一个基础项目。我习惯使用IntelliJ IDEA的内置工具但用命令行也很方便curl https://start.spring.io/starter.zip \ -d dependenciesweb,thymeleaf \ -d javaVersion17 \ -d packagingjar \ -d typegradle-project \ -o demo.zip关键是要包含这两个依赖Spring Web (提供MVC支持)Thymeleaf (模板引擎)2.2 配置Thymeleaf属性虽然SpringBoot已经提供了合理的默认配置但在实际开发中我通常会调整这些参数# application.yml spring: thymeleaf: prefix: classpath:/templates/ suffix: .html mode: HTML encoding: UTF-8 cache: false # 开发时关闭缓存 servlet: content-type: text/html reactive: max-chunk-size: 8192特别提醒cachefalse在开发阶段非常重要否则每次修改模板都要重启应用。我在第一个项目中就踩过这个坑调试了半天才发现是缓存问题。3. 第一个Thymeleaf页面开发3.1 创建基础模板在resources/templates下新建index.html!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org head meta charsetUTF-8 title用户管理系统/title /head body header th:fragmentheader h1欢迎来到用户管理系统/h1 /header section p当前时间span th:text${#temporals.format(currentTime, yyyy-MM-dd HH:mm)}/span/p /section /body /html注意几点必须添加xmlns:th命名空间声明th:fragment定义了可重用的模板片段#temporals是Thymeleaf内置的时间处理工具3.2 编写控制器创建对应的Controller类Controller public class HomeController { GetMapping(/) public String home(Model model) { model.addAttribute(currentTime, LocalDateTime.now()); return index; } }这个简单的例子展示了Thymeleaf的核心工作流程控制器准备数据返回视图名称Thymeleaf引擎将数据与模板结合生成最终HTML响应4. Thymeleaf高级特性实战4.1 布局复用技术大型项目中页面布局复用是关键。Thymeleaf通过Layout Dialect实现这点首先添加依赖implementation nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect然后创建基础布局文件layout.html!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org xmlns:layouthttp://www.ultraq.net.nz/thymeleaf/layout head title layout:title-pattern$CONTENT_TITLE - $LAYOUT_TITLE默认标题/title /head body header th:replace~{fragments/header :: header}/header section layout:fragmentcontent !-- 默认内容 -- /section footer th:replace~{fragments/footer :: footer}/footer /body /html具体页面可以这样使用布局!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org xmlns:layouthttp://www.ultraq.net.nz/thymeleaf/layout layout:decorate~{layout} head title用户列表/title /head body section layout:fragmentcontent !-- 页面特有内容 -- table !-- 用户列表 -- /table /section /body /html4.2 表单处理实战处理表单是Web开发的常见需求。看一个用户注册的例子表单页面form th:action{/register} th:object${user} methodpost div label用户名/label input typetext th:field*{username}/ /div div label密码/label input typepassword th:field*{password}/ /div button typesubmit注册/button /form控制器处理PostMapping(/register) public String register(Valid User user, BindingResult result) { if (result.hasErrors()) { return register; } // 保存用户逻辑 return redirect:/success; }这里有几个关键点th:object绑定表单对象th:field自动绑定字段支持Spring的验证机制处理完成后可以重定向5. 国际化与本地化实现5.1 多语言配置在resources下创建消息文件messages.properties(默认)messages_zh_CN.propertiesmessages_en_US.properties内容示例# messages_zh_CN.properties welcome.message欢迎来到系统 login.title用户登录 # messages_en_US.properties welcome.messageWelcome to our system login.titleUser Login5.2 动态切换语言创建配置类Configuration public class I18nConfig { Bean public LocaleResolver localeResolver() { CookieLocaleResolver resolver new CookieLocaleResolver(); resolver.setDefaultLocale(Locale.CHINA); resolver.setCookieName(lang); return resolver; } Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource source new ReloadableResourceBundleMessageSource(); source.setBasename(classpath:messages); source.setDefaultEncoding(UTF-8); return source; } }在页面中使用p th:text#{welcome.message}默认欢迎语/p语言切换控制器GetMapping(/changeLang) public String changeLang(RequestParam String lang, HttpServletRequest request, HttpServletResponse response) { LocaleResolver localeResolver RequestContextUtils.getLocaleResolver(request); localeResolver.setLocale(request, response, new Locale(lang)); return redirect: request.getHeader(Referer); }6. 性能优化与最佳实践6.1 模板缓存策略生产环境下一定要开启模板缓存spring: thymeleaf: cache: true但要注意修改模板后需要清除缓存。我通常采用以下方案开发环境保持关闭缓存生产环境开启缓存使用Spring Boot DevTools实现热加载6.2 静态资源处理正确配置静态资源位置spring: web: resources: static-locations: classpath:/static/在模板中引用静态资源link th:href{/css/style.css} relstylesheet script th:src{/js/app.js}/script img th:src{/images/logo.png}6.3 安全注意事项与Spring Security集成时要注意CSRF防护form th:action{/secure} methodpost input typehidden th:name${_csrf.parameterName} th:value${_csrf.token}/ !-- 其他表单字段 -- /form或者使用Security的自动集成form th:action{/secure} methodpost !-- 会自动添加CSRF令牌 -- /form7. 常见问题排查7.1 模板解析失败如果遇到模板解析错误首先检查模板文件是否放在templates目录下文件扩展名是否匹配配置的suffix是否添加了必要的命名空间声明7.2 表达式不生效表达式不渲染的可能原因控制器没有正确添加模型属性表达式语法错误使用了缓存但未刷新7.3 国际化失效多语言不生效时检查消息文件命名和位置是否正确是否配置了LocaleResolver浏览器语言设置是否正确在实际项目中我发现合理组织模板结构非常重要。通常我会这样划分目录templates/ ├── fragments/ # 可重用片段 ├── layouts/ # 布局文件 ├── shared/ # 共享组件 ├── admin/ # 管理后台页面 └── web/ # 前端页面这种结构让大型项目的模板管理变得清晰可控。另外我强烈建议在团队中制定Thymeleaf的编码规范比如统一使用th:前缀的属性顺序、片段命名规则等这能显著提高代码的可维护性。
SpringBoot3实战:Thymeleaf模板引擎的现代化Web开发指南
发布时间:2026/5/19 2:44:35
1. SpringBoot3与Thymeleaf的完美组合SpringBoot3作为当前Java生态中最流行的开发框架与Thymeleaf模板引擎的结合堪称Web开发的黄金搭档。我最近在一个电商后台管理系统的项目中就采用了这个技术组合实测下来开发效率提升了至少40%。Thymeleaf最大的优势在于它的自然模板特性。简单来说你写的HTML文件可以直接在浏览器中打开预览不需要启动服务端。当与SpringBoot3集成后这些静态HTML又能自动变成动态页面。这种开发体验对于前端和后端开发者来说都极其友好。在实际项目中我发现Thymeleaf特别适合以下场景需要快速开发的管理后台系统对SEO有要求的营销页面需要与SpringSecurity深度集成的系统多语言国际化的企业级应用2. 项目初始化与基础配置2.1 创建SpringBoot3项目首先用Spring Initializr创建一个基础项目。我习惯使用IntelliJ IDEA的内置工具但用命令行也很方便curl https://start.spring.io/starter.zip \ -d dependenciesweb,thymeleaf \ -d javaVersion17 \ -d packagingjar \ -d typegradle-project \ -o demo.zip关键是要包含这两个依赖Spring Web (提供MVC支持)Thymeleaf (模板引擎)2.2 配置Thymeleaf属性虽然SpringBoot已经提供了合理的默认配置但在实际开发中我通常会调整这些参数# application.yml spring: thymeleaf: prefix: classpath:/templates/ suffix: .html mode: HTML encoding: UTF-8 cache: false # 开发时关闭缓存 servlet: content-type: text/html reactive: max-chunk-size: 8192特别提醒cachefalse在开发阶段非常重要否则每次修改模板都要重启应用。我在第一个项目中就踩过这个坑调试了半天才发现是缓存问题。3. 第一个Thymeleaf页面开发3.1 创建基础模板在resources/templates下新建index.html!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org head meta charsetUTF-8 title用户管理系统/title /head body header th:fragmentheader h1欢迎来到用户管理系统/h1 /header section p当前时间span th:text${#temporals.format(currentTime, yyyy-MM-dd HH:mm)}/span/p /section /body /html注意几点必须添加xmlns:th命名空间声明th:fragment定义了可重用的模板片段#temporals是Thymeleaf内置的时间处理工具3.2 编写控制器创建对应的Controller类Controller public class HomeController { GetMapping(/) public String home(Model model) { model.addAttribute(currentTime, LocalDateTime.now()); return index; } }这个简单的例子展示了Thymeleaf的核心工作流程控制器准备数据返回视图名称Thymeleaf引擎将数据与模板结合生成最终HTML响应4. Thymeleaf高级特性实战4.1 布局复用技术大型项目中页面布局复用是关键。Thymeleaf通过Layout Dialect实现这点首先添加依赖implementation nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect然后创建基础布局文件layout.html!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org xmlns:layouthttp://www.ultraq.net.nz/thymeleaf/layout head title layout:title-pattern$CONTENT_TITLE - $LAYOUT_TITLE默认标题/title /head body header th:replace~{fragments/header :: header}/header section layout:fragmentcontent !-- 默认内容 -- /section footer th:replace~{fragments/footer :: footer}/footer /body /html具体页面可以这样使用布局!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org xmlns:layouthttp://www.ultraq.net.nz/thymeleaf/layout layout:decorate~{layout} head title用户列表/title /head body section layout:fragmentcontent !-- 页面特有内容 -- table !-- 用户列表 -- /table /section /body /html4.2 表单处理实战处理表单是Web开发的常见需求。看一个用户注册的例子表单页面form th:action{/register} th:object${user} methodpost div label用户名/label input typetext th:field*{username}/ /div div label密码/label input typepassword th:field*{password}/ /div button typesubmit注册/button /form控制器处理PostMapping(/register) public String register(Valid User user, BindingResult result) { if (result.hasErrors()) { return register; } // 保存用户逻辑 return redirect:/success; }这里有几个关键点th:object绑定表单对象th:field自动绑定字段支持Spring的验证机制处理完成后可以重定向5. 国际化与本地化实现5.1 多语言配置在resources下创建消息文件messages.properties(默认)messages_zh_CN.propertiesmessages_en_US.properties内容示例# messages_zh_CN.properties welcome.message欢迎来到系统 login.title用户登录 # messages_en_US.properties welcome.messageWelcome to our system login.titleUser Login5.2 动态切换语言创建配置类Configuration public class I18nConfig { Bean public LocaleResolver localeResolver() { CookieLocaleResolver resolver new CookieLocaleResolver(); resolver.setDefaultLocale(Locale.CHINA); resolver.setCookieName(lang); return resolver; } Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource source new ReloadableResourceBundleMessageSource(); source.setBasename(classpath:messages); source.setDefaultEncoding(UTF-8); return source; } }在页面中使用p th:text#{welcome.message}默认欢迎语/p语言切换控制器GetMapping(/changeLang) public String changeLang(RequestParam String lang, HttpServletRequest request, HttpServletResponse response) { LocaleResolver localeResolver RequestContextUtils.getLocaleResolver(request); localeResolver.setLocale(request, response, new Locale(lang)); return redirect: request.getHeader(Referer); }6. 性能优化与最佳实践6.1 模板缓存策略生产环境下一定要开启模板缓存spring: thymeleaf: cache: true但要注意修改模板后需要清除缓存。我通常采用以下方案开发环境保持关闭缓存生产环境开启缓存使用Spring Boot DevTools实现热加载6.2 静态资源处理正确配置静态资源位置spring: web: resources: static-locations: classpath:/static/在模板中引用静态资源link th:href{/css/style.css} relstylesheet script th:src{/js/app.js}/script img th:src{/images/logo.png}6.3 安全注意事项与Spring Security集成时要注意CSRF防护form th:action{/secure} methodpost input typehidden th:name${_csrf.parameterName} th:value${_csrf.token}/ !-- 其他表单字段 -- /form或者使用Security的自动集成form th:action{/secure} methodpost !-- 会自动添加CSRF令牌 -- /form7. 常见问题排查7.1 模板解析失败如果遇到模板解析错误首先检查模板文件是否放在templates目录下文件扩展名是否匹配配置的suffix是否添加了必要的命名空间声明7.2 表达式不生效表达式不渲染的可能原因控制器没有正确添加模型属性表达式语法错误使用了缓存但未刷新7.3 国际化失效多语言不生效时检查消息文件命名和位置是否正确是否配置了LocaleResolver浏览器语言设置是否正确在实际项目中我发现合理组织模板结构非常重要。通常我会这样划分目录templates/ ├── fragments/ # 可重用片段 ├── layouts/ # 布局文件 ├── shared/ # 共享组件 ├── admin/ # 管理后台页面 └── web/ # 前端页面这种结构让大型项目的模板管理变得清晰可控。另外我强烈建议在团队中制定Thymeleaf的编码规范比如统一使用th:前缀的属性顺序、片段命名规则等这能显著提高代码的可维护性。