代码改变世界

Spring Boot 2.7.8 集成 Thymeleaf:最佳实践与常见问题应对 - 详解

2026-01-27 17:11  tlnshuju  阅读(0)  评论(0)    收藏  举报

目录

前言

一、如何构建SpringBoot应用

1、项目依赖 (pom.xml)

2、控制器类

3、Thymeleaf 模板

4、配置文件 (application.yml)

5、主应用启动类

二、项目运行

1、项目启动

2、Restful接口测试

三、Thymeleaf集成的问题

1、异常详情

2、问题解决

四、总结


前言

        在当今快速发展的软件开发领域,构建高效、可维护且功能强大的 Web 应用是每个开发团队的追求目标。Spring Boot 作为一款备受推崇的 Java 基础框架,凭借其简洁的配置、强大的依赖管理和快速开发的特性,已经成为众多开发者的首选。与现在流行的Vue和React不同,Thymeleaf也是一种比较常见的模板引擎技术, Thymeleaf,作为一种现代的、功能丰富的模板引擎,以其自然模板的特性、与 HTML 的无缝兼容以及对静态原型的支持,成为与 Spring Boot 搭配构建 Web 应用的理想选择。

        为了帮助广大开发者更好地掌握 Spring Boot 2.7.8 与 Thymeleaf 的集成,本文将深入探讨这一主题。我们将从集成的基础开始,详细介绍如何在 Spring Boot 项目中引入 Thymeleaf,并进行必要的配置以确保它们能够协同工作。我们会分享一些最佳实践,包括如何组织模板文件、如何利用 Thymeleaf 的变量表达式和条件语句来构建动态页面,以及如何优化模板的加载和渲染性能。除了介绍集成的方法和技巧,本文还将重点关注开发过程中可能遇到的常见问题。我们会通过实际案例,分析这些问题产生的原因,并提供有效的解决方案。无论是处理模板路径的冲突、解决视图解析的错误,还是优化应用的启动时间,我们都会给出详细的步骤和代码示例,帮助读者快速定位并解决问题。当然现在Thymeleaf并不是前后端分离架构的最优解,因此本文给一些想学习SpringBoot的朋友提供示例说明和参考。

        通过阅读本文,你将能够更加深入地理解 Spring Boot 2.7.8 和 Thymeleaf 的集成机制,掌握最佳实践,避免常见的陷阱,并且能够快速应对开发过程中遇到的各种挑战。让我们一起踏上这段学习之旅,探索如何利用这两个强大的工具构建出卓越的 Web 应用。

一、如何构建SpringBoot应用

        Spring Boot 2.7.8 版本的发布,为开发者带来了更加稳定和优化的开发环境。它在性能、安全性以及兼容性等方面都有显著的提升,使得基于该版本构建的应用能够更好地适应各种复杂的业务场景。在这样的背景下,将 Thymeleaf 与 Spring Boot 2.7.8 进行集成,不仅可以充分发挥 Spring Boot 的优势,还能利用 Thymeleaf 强大的模板渲染能力,打造出用户体验出色、开发效率高的 Web 应用。本节将重点介绍如何快速构建SpringBoot应用,包括Pom.xml的定义、如何创建控制器类,如何创建Thyemleaf模板文件和主应用程序启动类。

1、项目依赖 (pom.xml)

        这里使用的JDK是1.8。因此这里使用SpringBoot2.7.8作为开发框架。如果对最新的SpringBoot有需要,也可以使用新版的springboot,集成过程大同小异。这里我们使用Maven的方式进行依赖管理。在Pom.xml中添加以下引用:


	4.0.0
	org.yelang
	baidu-sse-client
	0.0.1-SNAPSHOT
	
		org.springframework.boot
		spring-boot-starter-parent
		2.7.18 
		 
	
	
		1.8 
		UTF-8
		UTF-8
	
	
		
		
			org.springframework.boot
			spring-boot-starter-webflux
		
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
			com.fasterxml.jackson.core
			jackson-databind
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
			io.projectreactor
			reactor-test
			test
		
	
	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
			
			
				org.apache.maven.plugins
				maven-compiler-plugin
				
					1.8
					1.8
				
			
		
	

2、控制器类

        使用SpringBoot可以极大的简化我们开发Web应用后台。在Maven中引入了SpringBoot之后,我们就可以来创建控制器类,这里我们使用最简洁的方式来创建相关类。核心代码比较简单,这里直接给出源代码:

package org.yelang.controller;
import java.util.HashMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class TestController {
	@GetMapping("/test")
	public String test() {
		// 现在Thymeleaf会查找test.html
		return "test";
	}
	@GetMapping("/testa")
	@ResponseBody
	public Object testA() {
		HashMap data = new HashMap();
		data.put("name", "springboot");
		data.put("version", "v2.7.18");
		return data;
	}
}

        关于如何在SpringBoot中创建普通的接口和Restful接口,SpringBoot都是非常简单的,这里不做更多的赘述。上面第一个方式即是标准的MVC接口,最后返回一个页面给前端进行展示,第二个方式是返回一个对象信息。

3、Thymeleaf 模板

        接下来我们实现一个最简单的Thymeleaf html页面,核心代码如下:




    
    测试页面


    

测试页面

如果这个页面能正常显示,说明Thymeleaf配置正确。

返回首页

        通过前面的Controller中,通过test请求方法,就会跳转到这个具体的页面中。

4、配置文件 (application.yml)

        在SpringBoot中,约定大于配置是一条优化的规则,因此我们需要使用配置文件来进行应用程序的运行设置。比如程序运行端口号、访问路径、还有MVC模式下的访问页面配置,yml页面代码如下:

server:
  port: 8088
  servlet:
    context-path: /bdsse
spring:
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML
    encoding: UTF-8
    check-template-location: true
  mvc:
    static-path-pattern: /static/**
logging:
  level:
    com.example.sse: DEBUG

5、主应用启动类

        在springboot中,启动应用程序的方法很简单,直接就是Main的方法方便快捷。

package org.yelang;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SseClientApplication {
	public static void main(String[] args) {
        SpringApplication.run(SseClientApplication.class, args);
    }
}

二、项目运行

完成上述代码之后,我们就可以来运行项目。在启动应用程序后,同步测试一下应用接口的功能。

1、项目启动

        系统启动后,在控制台中可以看到以下内容,说明应用程序启动成功。

2、Restful接口测试

        在控制台中看到以下消息就表示启动成功,大家可以访问应用接口。

Started SseClientApplication in 4.953 seconds (JVM running for 5.594)

        在浏览器中输入以下地址,回车看到以下内容:

三、Thymeleaf集成的问题

        尽管 Spring Boot 和 Thymeleaf 的结合在理论上是完美的,但在实际开发过程中,开发者仍可能会遇到各种各样的问题。这些问题可能源于对框架特性的理解不够深入,也可能是因为开发环境的复杂性导致的配置冲突,甚至可能是由于一些隐藏的兼容性问题。这些问题如果不加以解决,可能会严重影响开发进度,降低应用的性能和稳定性。

1、异常详情

        如果是集成了MVC方法时,我们需要跳转到具体的页面,需要跳转到test.html中。在浏览器中输入访问地址后,看到的并不是我们的预期,而是以下错误:

        同时在我们的后台可以看到以下错误:

2025-11-21 22:23:49.561 ERROR 11996 --- [nio-8088-exec-7] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/bdsse] threw exception [Circular view path [test]: would dispatch back to the current handler URL [/bdsse/test] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause
javax.servlet.ServletException: Circular view path [test]: would dispatch back to the current handler URL [/bdsse/test] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
	at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:148) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1406) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1150) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) ~[tomcat-embed-core-9.0.83.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.31.jar:5.3.31]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) ~[tomcat-embed-core-9.0.83.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.31.jar:5.3.31]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.31.jar:5.3.31]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.31.jar:5.3.31]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.31.jar:5.3.31]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.31.jar:5.3.31]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.31.jar:5.3.31]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) ~[tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.83.jar:9.0.83]
	at java.lang.Thread.run(Unknown Source) [na:1.8.0_171]

        那么到底是什么原因导致的呢?通过排查问题来进行解决。

2、问题解决

        如果大家在搜索引擎上查找问题,可以看到一下内容,

        方法虽然多,但是基本很多都没有解决问题,都是把控制器的类型进行修改的,也有说明要调整配置文件。根据我的实测,都不是。在我这个场景中,实际问题是没有正确的引入Thymeleaf库,因此需要解决的问题就是在Pom.xml中引入相关资源,核心代码如下:



    org.springframework.boot
	spring-boot-starter-thymeleaf

        引入以上资源后,在此运行程序后,再次在浏览器中输入访问地址后可以看到以下效果:

        能看到以上页面,说明成功集成并且成功解决了以上的问题。

四、总结

        以上就是本文的主要内容,为了帮助广大开发者更好地掌握 Spring Boot 2.7.8 与 Thymeleaf 的集成,我们将从集成的基础开始,详细介绍如何在 Spring Boot 项目中引入 Thymeleaf,并进行必要的配置以确保它们能够协同工作。本文的目标读者是那些已经具备一定 Java 开发基础,并且对 Spring Boot 和 Thymeleaf 有一定了解的开发者。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。