目录
前言
一、如何构建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中添加以下引用:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.yelang</groupId>
<artifactId>baidu-sse-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version> <!-- 兼容JDK 8的Spring Boot版本 -->
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version> <!-- 使用JDK 8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- Spring Boot WebFlux (包含WebClient) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Spring Boot Web (可选,如果也需要传统Web MVC) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Jackson JSON处理 -->
<dependency>
<groupId>***.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 确保使用JDK 8编译 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-***piler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
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<String, Object> data = new HashMap<String, Object>();
data.put("name", "springboot");
data.put("version", "v2.7.18");
return data;
}
}
关于如何在SpringBoot中创建普通的接口和Restful接口,SpringBoot都是非常简单的,这里不做更多的赘述。上面第一个方式即是标准的MVC接口,最后返回一个页面给前端进行展示,第二个方式是返回一个对象信息。
3、Thymeleaf 模板
接下来我们实现一个最简单的Thymeleaf html页面,核心代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页面</title>
</head>
<body>
<h1>测试页面</h1>
<p>如果这个页面能正常显示,说明Thymeleaf配置正确。</p>
<a href="/">返回首页</a>
</body>
</html>
通过前面的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:
***.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.***.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794) [tomcat-embed-core-9.0.83.jar:9.0.83]
at org.apache.tomcat.util.***.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中引入相关资源,核心代码如下:
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
引入以上资源后,在此运行程序后,再次在浏览器中输入访问地址后可以看到以下效果:
能看到以上页面,说明成功集成并且成功解决了以上的问题。
四、总结
以上就是本文的主要内容,为了帮助广大开发者更好地掌握 Spring Boot 2.7.8 与 Thymeleaf 的集成,我们将从集成的基础开始,详细介绍如何在 Spring Boot 项目中引入 Thymeleaf,并进行必要的配置以确保它们能够协同工作。本文的目标读者是那些已经具备一定 Java 开发基础,并且对 Spring Boot 和 Thymeleaf 有一定了解的开发者。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。