Java高级 | 【实验三】Springboot 静态资源访问
隶属文章: Java高级 | (二十二)Java常用类库-CSDN博客
系列文章: Java高级 | 【实验一】Spring Boot安装及测试 最新-CSDN博客
Java高级 | 【实验二】Springboot 控制器类+相关注解知识-CSDN博客
目录
一、Thymeleaf
1.1 是什么?
1.2 Thymeleaf机制说明
1.3 优点VS缺点
1.4 使用Thymeleaf
(1)jar包依赖
(2)在application.properties中配置thymeleaf
二、Thymeleaf语法
2.1 chongyoth属性
①文本替换(th:text)
②HTML 替换(th:utext)
2.2 其他th 属性
三、spring boot使用Thymeleaf
3.1 创建spring boot工程并默认使用thymeleaf模板引擎
3.2 编写控制器类及数据对象类
3.3 编写前端视图页面
(1)编写test1.html
(2)编写test2.html
(3)编写test3.html
(4)编写test4.html
四、练习题
【问题】
【答案】
Web 开发离不开动态页面的开发,很早以前企业主要使用JSP技术来开发网页,随着技术的升级更替,目前来说主流的方案是Thymeleaf。
Thymeleaf 是一个模板框架,它可以支持多种格式的内容动态渲染,功能非常强大,它天然和 HTML是相融合的,所以对于前端工程师来说它也是易于理解的。
Springboot默认是不支持JSP的,默认使用Thymeleaf模板引擎。
官方文档:Tutorial: Using Thymeleaf
一、Thymeleaf
1.1 是什么?
- 是一个跟 Velocity、FreeMarker 类似的模板引擎,可完全替代 JSP。
- 是一个 java 类库,它是一个 xml/xhtml/html5 的模板引擎,可以作为mvc的web应用的view层。
1.2 Thymeleaf机制说明
Thymeleaf 是服务器渲染技术,页面数据是在服务器端进行渲染的。
因此,在开发中使用Thymeleaf,并不是前后端分离。
1.3 优点VS缺点
- 开箱即用,它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言;
- Thymeleaf模板页面无需服务器渲染,也可以被浏览器运行,页面简洁SpringBoot支持 Thymeleaf、Velocity、FreeMarker。
- 并不是一个高性能的引擎,适用于单体应用。如果要做一个高并发的应用,选择前后端分离更好,但是作为SpringBoot推荐的模板引擎,还是需要了解一下。
1.4 使用Thymeleaf
(1)jar包依赖
在pom.xml中添加如下依赖:
//这个配置是必须的,事实上,spring boot项目创建好后,已自动添加该依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
(2)在application.properties中配置thymeleaf
//这个配置不是必须的
//但是spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求。
spring.thymeleaf.mode = LEGACYHTML5
二、Thymeleaf语法
2.1 chongyoth属性
html有的属性,Thymeleaf基本都有,而常用的属性大概有七八个。其中th属性执行的优先级从1~8,数字越低优先级越高。
属性 | 作用描述 | 相关属性 | 优先级(order) | 说明 |
th:insert | 代码块引入 | th:replace, th:include | 1 | 优先级最高,常用于公共代码块提取 三者的区别较大,若使用不恰当会破坏html结构 |
th:each | 遍历循环元素 | 与 th:text、th:value 一起使用 | 2 | 优先级很高,注意修饰标签位置 |
th:if | 条件判断 | th:unless, th:switch, th:case | 3 | 优先级较高 |
th:object | 声明变量,配合 *{} 使用,达到偷懒的效果 | - | 4 | 优先级一般,用于简化表达 |
th:attr | 修改任意属性 | th:attrappend, th:attrprepend | 5 | 优先级一般,实际开发中用的较少,因为有丰富的其他th属性帮忙,类似的还有th:attrappend,th:attrprepend |
th:value | 设置当前元素的 value 值,类似修改指定属性 | th:src, th:href | 6 | 优先级不高 |
th:text | 设置当前元素的文本内容 | th:utext | 7 | 优先级不高,th:text会转义HTML标签,th:utext不会 |
th:fragment | 定义代码块,供 th:insert 引用 | - | 8 | 优先级最低 |
①文本替换(th:text)
文本替换是指直接将变量的值替换到 HTML 标签的文本内容中。
在 Thymeleaf 中,可以使用th:text属性来实现文本替换。
<p th:text="${user.name}">Default Text</p>
在这个例子中,${user.name} 的值会替换 <p> 标签中的文本内容,如果user.name存在,则其值会显示在页面上;如果不存在,则显示默认文本"Default Text"。
②HTML 替换(th:utext)
HTML 替换是指将变量的值作为 HTML 内容插入到 HTML 标签中。在 Thymeleaf 中,可以使用th:utext属性来实现 HTML 替换。
<div th:utext="${user.description}">Default HTML</div>
在这个例子中,${user.description} 的值会被作为 HTML 内容插入到 <div> 标签中,不会被转义处理。这意味着,如果${user.description}的值包含 HTML 标签,它们会被正确地解析并显示在页面上。
2.2 其他th 属性
Thymeleaf 还提供了大量的 th 属性,这些属性可以直接在 HTML 标签中使用,其中常用 th 属性及其示例如下表。
属性 | 描述 | 示例 |
th:id | 替换 HTML 的 id 属性 | <input id="html-id" th:id="thymeleaf-id" /> |
th:text | 文本替换,转义特殊字符 | <h1 th:text="hello,bianchengbang" >hello</h1> |
th:utext | 文本替换,不转义特殊字符 | <div th:utext="<h1>欢迎来到编程帮!</h1>" >欢迎你</div> |
th:object | 在父标签选择对象,子标签使用 *{…} 选择表达式选取值。 | <div th:object="${session.user}" > <p th:text="*{fisrtName}">firstname</p> </div> |
th:value | 替换 value 属性 |
|
th:with | 局部变量赋值运算 |
|
th:style | 设置样式 |
|
th:onclick | 点击事件 |
|
th:each | 遍历,支持 Iterable、Map、数组等。 |
|
th:if | 根据条件判断是否需要展示此标签 |
|
th:unless | 和 th:if 判断相反,满足条件时不显示 |
|
th:switch | 与 Java 的 switch case语句类似 |
|
th:fragment | 模板布局,类似 JSP 的 tag,用来定义一段被引用或包含的模板片段 |
|
th:insert | 布局标签; |
|
th:replace | 布局标签; |
|
th:selected | select 选择框选中 |
|
th:src | 替换 HTML 中的 src 属性 |
|
th:inline | 内联属性; |
|
th:action | 替换表单提交地址 |
|
三、spring boot使用Thymeleaf
3.1 创建spring boot工程并默认使用thymeleaf模板引擎
File->New->Project
至此,一个基于spring boot的web工程已创建完毕,该工程默认的前端模板是Thymeleaf。
运行工程,如果能运行成功。则编写控制器类。
如果不能正常运行,请根据提示信息修改工程的配置,可能修改pom.xml,可能修改工程的结构(快捷键shift+ctrl+alt+s)等。
3.2 编写控制器类及数据对象类
在当前包com.example.thymeleaftest中创建控制器类及数据对象类。
(1)创建 MyData1类
//存放数据对象
package com.example.thymeleaftest;public class MyData1 {private int id = 0;private String username="";private String password="";public MyData1() {}public MyData1(int id, String username, String password) {this.id = id;this.username = username;this.password = password;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "MyData1{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
(2)编写控制器类 TestController
用于跳转到视图层并传递相关数据给指定的视图层。
package com.example.thymeleaftest;import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.ArrayList;
import java.util.List;@Controller//该注解表明TestController类是一个控制器
@RequestMapping("/test")//注解TestController类所有方法访问的url是http://localhost8080/test
public class TestController {@RequestMapping("/test1")//该方法处理的url是http://localhost8080/test/test1public String test1() {return "test1";//转发给视图test1.html}@RequestMapping("/test2")//该方法处理的url是http://localhost8080/test/test2public String test2(Model model) {//参数model为模型,用来存放转发到视图的数据String name = "Jack";model.addAttribute("name", name);//模型中填充数据,该数据在视图的中名称为namereturn "test2";}@RequestMapping("/test3")//该方法处理的url是http://localhost8080/test/test3public String test3(Model model) {List<MyData1> myList = new ArrayList<>();myList.add(new MyData1(1, "laisc", "lai1203"));myList.add(new MyData1(2, "admin", "admin888"));myList.add(new MyData1(3, "root", "root9812"));model.addAttribute("userlist", myList);return "test3";}@RequestMapping("/test4")//该方法处理的url是http://localhost8080/test/test4public String test4(Model model) {MyData1 mydata1 = new MyData1(1, "admin", "admin1234");model.addAttribute("data123", mydata1);return "test4";}@RequestMapping("/test5")//该方法处理的url是http://localhost8080/test/test2public String test5(HttpServletRequest request) {String name = "张三";request.setAttribute("name", name);return "test2";}
}
上面的控制类一个定义了5个方法,每个方法都定义了其前端访问的url,以及返回到视图的数据。
3.3 编写前端视图页面
前端视图用的是thymeleaf模板,而thymeleaf模板默认的路径是/resources/templates。因此,我们在templates文件夹中创建4个html页面,分别是test1.html、test2.html、test2.html和test4.html,即4个视图页面。如图4所示:
(1)编写test1.html
该视图对应TestController控制器类的test1()方法,该方法没有传递任何数据到test1.html视图。test1.html视图直接输出“Hello, world!”,其代码如下所示。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
Hello, world!
</body>
</html>
说明:由于该视图没有输出变量的值,因此可以使用传统的html代码。
(2)编写test2.html
该视图对应TestController控制器类的test2()方法,该方法传递一个“name”变量到test2.html视图。test2.html视图输出“name”变量的值。其代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'"></p>
</body>
</html>
- <html xmlns:th="http://www.thymeleaf.org">---导入thymeleaf资源说明:由于该视图要输出变量的值,因此必须使用thymeleaf+html代码。
- <p th:text="'Hello, ' + ${name} + '!'">3333</p>----输出变量。
(3)编写test3.html
该视图对应TestController控制器类的test3()方法,该方法传递一个list集合到 test3.html视图,视图循环输出集合的值。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<table><tr><th>ID</th><th>username</th><th>password</th></tr><tr th:each="user : ${userlist}"><td th:text="${user.id}">-1</td><td th:text="${user.username}">abc</td><td th:text="${user.password}">555</td></tr>
</table>
</body>
</html>
(4)编写test4.html
该视图对应TestController控制器类的test3()方法,该方法传递一个model对象到test4.html视图.该视图把对象的值输出到超链接的参数值。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${data123.username})}">链接1</a>
<a href="details.html" th:href="@{/order/details(orderId=${data123.username})}">链接2</a>
<a href="abc.html" th:href="'order/'+${data123.id}+'/details?orderId='+${data123.username} ">链接3</a>
<a href="abc.html" th:href="@{'/details/'+${data123.id}(orderId=${data123.username})}">链接4</a>
<a href="abc.html" th:href="@{'/details/'+${data123.id}+'/aaa'(orderId=${data123.username})}">链接5</a>
</body>
</html>

四、练习题
【问题】
编写一个控制器,产生100个学生对象,并把这些对象在html中以表格的形式输出。
【答案】
package com.example.thymeleaftest;public class Student {private int id;private String name;private int age;public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}// Getter方法public int getId() { return id; }public String getName() { return name; }public int getAge() { return age; }
}
package com.example.thymeleaftest;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;@Controller
@RequestMapping("/student")
public class StudentController {@RequestMapping("/list")public String listStudents(Model model) {List<Student> students = new ArrayList<>();// 生成100个简单学生数据for (int i = 1; i <= 100; i++) {students.add(new Student(i, "学生" + i, 18 + (i % 7)));}model.addAttribute("students", students);return "studentList";}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>学生列表</title>
</head>
<body>
<h1>学生列表</h1>
<table border="1"><tr><th>ID</th><th>姓名</th><th>年龄</th></tr><tr th:each="student : ${students}"><td th:text="${student.id}"></td><td th:text="${student.name}"></td><td th:text="${student.age}"></td></tr>
</table>
</body>
</html>
相关文章:

Java高级 | 【实验三】Springboot 静态资源访问
隶属文章: Java高级 | (二十二)Java常用类库-CSDN博客 系列文章: Java高级 | 【实验一】Spring Boot安装及测试 最新-CSDN博客 Java高级 | 【实验二】Springboot 控制器类相关注解知识-CSDN博客 目录 一、Thymeleaf 1.1 是什么&…...
C语言_预处理详解
1. 预定义符号 C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的 1 __FILE__ //进行编译的源文件 2 __LINE__//文件当前的行号 3 __DATE__ //文件被编译的日期 4 __TIME__//文件被编译的时间 5 __STDC__//如果编译器遵循ANSI…...
将前后端分离版的前端vue打包成EXE的完整解决方案
将若依前后端分离版的前端打包成EXE的完整解决方案 将若依前后端分离版的Vue前端打包成Windows可执行文件(.exe),同时保持与后端API的通信,需要使用Electron框架来实现。下面是详细的步骤和解决方案。 一、准备工作 1. 环境要求 Node.js (推荐v16+)npm 或 yarn若依前后端分…...
物联网协议之MQTT(一)基础概念和设备
前言: 本文内容均以实战出发,像MQTT概念这种基础内容建议大家自行百度。 推荐资料: mica-mqtt文档 一、MQTT简单介绍 作为当今物联网的主流协议,MQTT的使用范围非常广,如果你想了解甚至是从事物联网行业,…...

「Java教案」Java程序的构成
课程目标 1.知识目标 能够按照Java标识符的命名规则,规范变量的命名。能够区分Java中的关键字与保留字。能够对注释进行分类,根据注释的用途合理的选择注释方式。 2.能力目标 能编写符合规范的标识符。能识别Java中的关键字和…...
还原Windows防火墙
还原Windows防火墙 1. 背景2. 为何“还原”完胜“关闭”?三大核心优势3. 还原防火墙默认值操作步骤4. 还原防火墙时,系统背后的工作5. 需要还原防火墙场景一招拯救混乱网络!还原Windows防火墙,找回你的“安全速度”1. 背景 你是否曾因一时误操作关闭了Windows防火墙?是…...

区块链可投会议CCF B--EDBT 2026 截止10.8 附录用率
Conference:EDBT: 29th International Conference on Extending Database Technology CCF level:CCF B Categories:数据库/数据挖掘/内容检索 Year:2026 Conference time:24th March - 27th…...

经典ReLU回归!重大缺陷「死亡ReLU问题」已被解决
来源 | 机器之心 在深度学习领域中,对激活函数的探讨已成为一个独立的研究方向。例如 GELU、SELU 和 SiLU 等函数凭借其平滑梯度与卓越的收敛特性,已成为热门选择。 尽管这一趋势盛行,经典 ReLU 函数仍因其简洁性、固有稀疏性及…...

在VSCode中开发一个uni-app项目
创建项目 使用命令行工具(例如 vue-cli)来创建一个新的 uni-app 项目。 创建以JavaScript开发的工程 npx degit dcloudio/uni-preset-vue#vite my-vue3-project //或者 npx degit dcloudio/uni-preset-vue#vite-alpha my-vue3-project创建以TypeScript…...
quic为什么没有被大规模应用?
一、成本 将应用程序从 HTTP/2 迁移到 HTTP/3,或从 TCP 迁移到 UDP 需要付出一定的努力。它需要将整个应用层实现和传输层实现转换到UDP,并在服务器端和客户端构建一个全新的解决方案。对于资源有限的小型流媒体供应商来说,这是一个不小的挑…...
Delft3D软件介绍及建模原理和步骤;Delft3D数值模拟溶质运移模型建立;地表水环境影响评价报告编写思路
📚 教程以地表水数值模拟软件 Delft3D 4.03.00 的操作为核心内容,系统涵盖地表水水动力建模、基础资料获取、边界条件设定、模型率定与验证以及数据分析处理等关键环节。通过全面讲解,学员将掌握地表水数值模拟的全过程实际操作技术。 &…...
书籍在其他数都出现k次的数组中找到只出现一次的数(7)0603
题目 给定一个整型数组arr和一个大于1的整数k。已知arr中只有1个数出现了1次,其他的数都出现了k次,请返回只出现了1次的数。 解答: 对此题进行思路转换,可以将此题,转换成k进制数。 k进制的两个数c和d,…...
开源模型应用落地-OpenAI Agents SDK-集成Qwen3-8B-function_tool(二)
一、前言 在人工智能技术迅猛发展的今天,OpenAI Agents SDK 为开发者提供了一个强大的工具集,用于构建基于 Python 的智能代理应用。这些代理可以执行从简单任务到复杂决策的一系列操作,极大地提升了应用程序的智能化水平。 通过 OpenAI Agents SDK,可以利用 Python 编程语…...

Python - 爬虫;Scrapy框架之插件Extensions(四)
阅读本文前先参考 https://blog.csdn.net/MinggeQingchun/article/details/145904572 在 Scrapy 中,扩展(Extensions)是一种插件,允许你添加额外的功能到你的爬虫项目中。这些扩展可以在项目的不同阶段执行,比如启动…...

Spark实战能力测评模拟题精析【模拟考】
1.println(Array(1,2,3,4,5).filter(_%20).toList() 输出结果是(B) A. 2 4 B. List(2,4) C. List(1,3,5) D. 1 3 5 2.println(Array("tom","team","pom") .filter(_.matches("")).toList) 输出结果为(List(tom,…...

【OSG学习笔记】Day 15: 路径动画与相机漫游
本章来学习下漫游相机。 路径动画与相机漫游 本届内容比较简单,其实就是实现物体的运动和相机的运动 当然这两个要一起执行。 贝塞尔曲线 贝塞尔曲线(Bzier curve)是一种在计算机图形学、动画制作、工业设计等领域广泛应用的参数曲线&am…...

PostgreSQL(PostGIS)触发器+坐标转换案例
需求,只录入一份坐标参考为4326的数据,但是发布的数据要求坐标必须是3857 对这种需求可以利用数据库触发器实现数据的同步 步骤: 1. 使用ArcGIS Pro创建一个名字为testfc_4326的图层,坐标参考为4326 2. 使用Pro再创建一个名字…...

Constraints and Triggers
目录 Kinds of Constraints Single-Attribute Keys Multiattribute Key Foreign Keys Expressing Foreign Keys Enforcing Foreign-Key Constraints Actions Taken Attribute-Based Checks Timing of Checks Tuple-Based Checks Assertions Timing of Assertion Ch…...
基于windows系统的netcore架构与SqlServer数据库,实现双机热备。
以下是基于 SQL Server Always On 可用性组 和 故障转移群集 的详细配置步骤,用于实现双机热备。 步骤 1:准备环境 1.1 硬件和软件准备 两台服务器:分别作为主服务器和备用服务器。SQL Server版本:确保两台服务器上安装的SQL S…...
【转bin】EXCEL数据转bin
如果DEC2BIN函数的默认设置无法满足需求(它最多只能处理10位的二进制转换),可以通过VBA宏方法来处理较大数的二进制转换并提取特定位置的数字: 十进制转二进制(不限位宽) 1、打开VBA编辑器(Al…...

BERT:让AI真正“读懂”语言的革命
BERT:让AI真正“读懂”语言的革命 ——图解谷歌神作《BERT: Pre-training of Deep Bidirectional Transformers》 2018年,谷歌AI团队扔出一篇核弹级论文,引爆了整个NLP领域。这个叫BERT的模型在11项任务中屠榜,甚至超越人类表现…...
【计算机组成原理】SPOOLing技术
SPOOLing技术 关键点内容核心思想通过输入/输出井虚拟化独占设备,实现共享,即让多个作业共享一台独占设备依赖条件1. 外存(井文件)2. 多道程序设计虚拟实现多道程序技术磁盘缓冲数据流方向输入设备 → 输入井 → CPU → 输出井 →…...

冷雨泉教授团队:新型视觉驱动智能假肢手,拟人化抓握技术突破,助力截肢者重获生活自信
研究背景:日常生活中,健康人依靠手完成对物体的操作。对于手部截肢患者,手部的缺失导致他们难以有效地操作物体,进而影响正常的日常生活。拥有一个能够实现拟人地自然抓取多种日常物体的五指动力假手是手部截肢患者的夙愿…...
CanvasGroup篇
🎯 Unity UI 性能优化终极指南 — CanvasGroup篇 🧩 什么是 CanvasGroup? CanvasGroup 是UGUI的透明控制器,用于整体控制一组UI元素的: 可见性 (alpha)交互性 (interactable)射线检测 (blocksRaycasts) 🎯…...
[Java 基础]银行账户程序
编写一个 Java 控制台应用程序,模拟一个简单的银行账户。该程序应允许用户执行以下操作: 查询账户余额。 账户初始余额设置为 1000.0 元。向账户存入资金。 用户可以输入存款金额,程序应更新账户余额。存款金额必须为正数。从账户提取资金。…...
2025.6.4总结
工作:今天效率比较高,早上回归4个问题,下午找了3个bug,晚上二刷了科目一(贪吃蛇系统),写了四个点,唯一没达标的就是两自动化没完成。美中不足的是电脑上下载不了PC版的番茄工作软件。…...
将音频数据累积到缓冲区,达到阈值时触发处理
实现了音频处理中的 AEC(声学回声消除)和 AES(音频增强)功能,其核心功能是: 数据缓冲管理:将输入的麦克风和扬声器音频数据块累积到缓冲区中块处理机制:当缓冲区填满预设大小&#…...

pikachu靶场通关笔记14 XSS关卡10-XSS之js输出(五种方法渗透)
目录 一、源码分析 1、进入靶场 2、代码审计 二、渗透实战 1、根据提示输入tmac 2、XSS探测 3、注入Payload1 4、注入Payload2 5、注入Payload3 6、注入Payload4 7、注入Payload5 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合&#x…...
5.Promise,async,await概念(1)
Promise 是 JavaScript 原生提供的异步处理机制,而 async 和 await 是基于 Promise 的语法糖,由 JavaScript 语言和其运行时环境(如浏览器、Node.js)支持,用于更清晰地编写异步代码,从而避免回调地狱。 Pr…...

李沐-动手学深度学习:RNN
1.RNN从零开始实现 import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2l#8.3.4节 #batch_size:每个小批量中子序列样本的数目,num_steps:每个子序列中预定义的时间步数 #loa…...