Spring Boot 学习之路 -- Thymeleaf 模板引擎

在这里插入图片描述

前言

  1. 最近因为业务需要,被拉去研究后端的项目,代码框架基于 Spring Boot,后端对我来说完全小白,需要重新学习研究…
  2. 出于个人习惯,会以 Blog 文章的方式做一些记录,文章内容基本来源于「 Spring Boot 从入门到精通(明日科技) 」一书,做了一些整理,更易于个人理解和回顾查找,所以大家如果希望更系统性的学习,可以阅读此书。

系列文章
Spring Boot 学习之路📑 基础认知
Spring Boot 学习之路📑 项目配置
Spring Boot 学习之路📑 处理 HTTP 请求
Spring Boot 学习之路📑 Service 层
Spring Boot 学习之路📑 Thymeleaf 模板引擎

一、概述

Spring Boot 遵循“前后端分离”的设计理念。所谓的“前后端分离”中的前端指网页端、客户端,后端指服务器端。后端只提供服务接口,前端只有通过访问后端接口才能获取到数据。此外,前端还要完成页面的布局、渲染等工作。如果想让前端获取的数据可以根据用户的操作而发生变化,就需要使用动态网页技术。为此,Spring Boot 采用了 Web 模板引擎技术。Thymeleaf 是 Spring Boot 官方推荐使用的模板引擎。

Thymeleaf 是一个 Java 模板引擎,适用于 Web 开发和独立环境的服务器端。那么,什么是模板引擎呢?模板引擎是为了使用户界面与业务数据分离而生成的特定文本格式的文档,常用的文本格式有 HTML、XML 等。

Thymeleaf 的主要目标是提供一种可以被浏览器正确显示的、格式良好的模板创建方式。在实际开发中,程序开发人员可以使用 Thymeleaf 创建 XML 和 HTML 模板。所谓 XML 和 HTML 模板,指的是格式良好的 .html 文件。也就是说,Thymeleaf 把 .html 文件作为模板。与编写逻辑代码相比,程序开发人员只需要把标签属性添加到 .html 文件中,即可执行预先制定好的逻辑。

Thymeleaf 具有如下两个特点:

  • Thymeleaf 在有网络、无网络的环境下都可以运行。Thymeleaf 可以直接在浏览器中打开并查看静态页面。Thymeleaf 可以通过向 HTML 标签中添加其他属性实现数据渲染。
  • Thymeleaf 具有“开箱即用”的特性。Thymeleaf 直接以 .html 的格式予以显示。Thymeleaf 可以使前后端很好地分离。

二、添加 Thymeleaf

Thymeleaf 需要手动添加到 Spring Boot 项目中。添加 Thymeleaf 的方式有两种:

  1. 第一种是在创建项目的添加依赖界面中选择 Thymeleaf:

在这里插入图片描述

  1. 第二种是在已创建好的项目的 pom.xml 文件中添加以下依赖:
<dependency>
​​​​     <groupId>org.springframework.boot</groupId>
​​​​     <artifactId>spring-boot-starter-thymeleaf</artifactId>
​​​​</dependency>

三、跳转至 .html 文件

在前面文章的实例中,控制器都是直接返回字符串,或者是跳转至其他 URL 地址。如果想让控制器跳转至项目中的某个 .html 文件,就需要使用 Thymeleaf 了。

3.1 明确 .html 文件的存储位置

Spring Boot 项目中所有页面文件都要放在 src/main/resources 目录的 templates 文件夹下。页面可能需要加载一些静态文件,例如图片、JS 文件等,静态文件需要放在与 templates 同级的 static 文件夹下。

在这里插入图片描述

3.2 跳转至指定的 .html 文件

前面曾介绍了两种控制器注解:@Controller@RestController。@Controller 中的方法如果返回字符串,则默认访问返回值对应的地址。如果项目添加了 Thymeleaf 依赖则会改变此处跳转的逻辑,Thymeleaf 会根据返回的字符串值,寻找 templates 文件夹下同名的网页文件,并跳转至该网页文件。例如,下图所示,如果方法的返回值为“login”,Thymeleaf 在 templates 文件夹下发现了 login.html 文件,则会让其请求跳转至该文件。如果方法返回值没有对应的 .html 文件,则会抛出 TemplateInputException 异常。

在这里插入图片描述

说明:
想要实现此功能的控制器,必须用 @Controller 标注,不能使用 @RestController。
templates 文件夹下的 .html 文件无法通过 URL 地址直接访问,只能通过 Controller 类跳转。
html 文件可以放在 static 文件夹下,这样 .html 文件就是静态页面,可以直接通过 URL 地址访问,但无法获得动态数据。

3.3 跳转至 Thymeleaf 的默认页面

在不指定项目主页和错误页跳转规则的前提下,Thymeleaf 模板会默认将 index.html 当作项目的默认主页,将 error.html 当作项目默认错误页。如果发生的异常没有被捕捉,就自动跳转至 error.html。

注意:
默认的 index.html 和 error.html 必须在 templates 文件夹根目录下。

  1. 为项目添加默认首页

在 templates 文件夹下创建 index.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>这是 Thymeleaf 默认的首页</h1>
</body>
</html>

创建 IndexController 控制器类,如果用户访问 “/login” 地址,则必须传入 name 参数。IndexController 类的代码如下:

public class IndexController {@RequestMapping("/login")public String login(@RequestParam String name) {return "您输入的用户名为:" + name;}
}

启动项目后,打开浏览器访问 http://127.0.0.1:8080 地址,可以看到下图的默认首页。

在这里插入图片描述

访问地址 http://127.0.0.1:8080/login?name=David 可以看到控制器返回如下界面:

在这里插入图片描述


四、常用表达式和标签

Thymeleaf 提供了许多独有的标签,程序开发人员可以利用这些标签让页面显示动态的内容。Thymeleaf 也提供了几个表达式用来为标签赋值。本节将介绍一些常用的表达式和标签。

4.1 表达式

Thymeleaf 有 4 种常用的表达式,分别用于不同场景,下面分别介绍。

1. 读取属性值

后端向前端发送的数据都会放在 Model 对象中,存放格式类似键值结构,就是“属性名:属性值”的结构。在页面中可以利用 *{} 表达式通过属性名获得 Model 中属性值。表达式语法如下:

​​​​*{属性名}​​

例如,获取属性名为 name 的值:

​​​​*{name}​​

2. 读取对象

如果后端向前端发送的不是一个具体值,而是一个对象(例如日期对象、集合对象等),想要调用该对象中的属性或方法,必须使用 ${} 表达式。表达式语法如下:

​​​​${对象}
​​​​${对象.属性}
​​​​${对象.方法()}​​

${对象}获得的是对象,而不是一个具体值,所以需要配合遍历、定义变量等标签一起使用。${对象.方法()} 获得的是该对象方法的返回值。

3. 封装地址

如果想要在 Thymeleaf 标签中赋值具体的 URL 地址,需要用到 @{} 表达式。表达式语法如下:

​​​​@{/URL地址}​​

使用该表达式可以为标签定义跳转地址。

4. 插入片段

插入片段表达式的功能类似 JSP 中的 jsp:include 标签,允许程序开发人员将 A 页面中的代码插入到 B 页面中。表达式语法如下:

​​​​~{创建片段的文件名::片段名}​​

该表达式必须配合 th:fragment 标签,在定义完代码片段之后使用。注意该表达式的写法比较特殊,“创建片段的文件名”是代码片段所在文件的抽象名称,例如代码片段定义在 src/main/resources/templates/top/head.html 页面文件中,文件名应该写为“top/head”,不包含根目录名和后缀名。“片段名”为 th:fragment 标签定义的名称。表达式中间有两个冒号而不是一个。

4.2 标签

很多表达式都需要配合标签一起使用,Thymeleaf 提供的标签非常多,基本满足了所有动态页面的需求。下图表中列出了一些常用的标签,想要使用这些标签,就必须先在页面顶部导入标签,代码如下:

​​​​<html xmlns:th="http://www.thymeleaf.org">​​

导入之后就可以把 Thymeleaf 的标签以标签属性的形式写在 HTML 各元素之中。

在这里插入图片描述


五、向前端页面传值

Thymeleaf 从后端向前端页面传值的语法比 JSP 技术简洁许多。本节将介绍使用 Thymeleaf 向前端页面传值的两步操作。

5.1 把要传的值添加到 Model 对象中

Model 是 org.springframework.ui 包下的接口,用法类似 Map 键值对。Model 接口提供的接口如下:

在这里插入图片描述

程序开发人员只需为 Controller 的跳转方法添加 Model 参数,然后把要传给前端的值保存成 Model 的属性,Thymeleaf 可以自动读取 Model 里的属性值,并将其写入前端页面中。例如,把用户名 “张三” 传输给前端,可以参照如下代码:

​​​​@RequestMapping("/index")
​​​​public String show(Model model) {
​​​​    model.addAttribute("name", "张三";
​​​​    return "index";
​​​​}​​

5.2 在前端页面中获取 Model 的属性值

前端读取 Model 的属性值时需要用到 *{} 或 ${} 表达式。如果读取基本数据类型或字符串,就用*{},例如 *{name} 即可读取 Model 中名为 name 的属性值。

比如,我们做个测试:在前端页面显示用户的 IP 地址信息。

  1. 创建 ParameterController 控制器类,为映射 “/index” 的方法添加 Model 参数和 HttpServletRequest 参数。获取发送请求的 IP 地址、请求类型,以及请求头中的浏览器类型,将这些数据都保存在 Model 的属性中,最后跳转至 main.html。

ParameterController 类的代码如下:

@Controller
public class ParameterController {@RequestMapping("/index")public String index(Model model, HttpServletRequest request) {model.addAttribute("ip", request.getRemoteAddr());                 // 记录请求 IP 地址model.addAttribute("method", request.getMethod());				   // 记录请求类型String brow = "未知";String userAgent = request.getHeader("User-Agent").toLowerCase();  // 读取请求头if (userAgent.contains("Chrome")) {								   // 如果包含谷歌浏览器名称brow = "谷歌浏览器";} else if (userAgent.contains("Firefox")) {						   // 如果包含火狐浏览器名称brow = "火狐浏览器";}model.addAttribute("brow", brow);								   // 记录浏览器识别结果return "main";}
}
  1. 在 main.html 中获取 Model 中的 IP 地址、请求类型和浏览器类型的值,展示在页面中。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p th:text=" '您的 IP 地址:' + ${ip}"></p><p th:text=" '您提供的方式:' + ${method}"></p><p th:text=" '您使用的浏览器:' + ${brow}"></p>
</body>
</html>

启动项目后,访问 http://127.0.0.1:8080/index 地址。

在这里插入图片描述


六、内置对象

除了之前介绍的表达式和标签,Thymeleaf 还提供了一些内置对象,程序开发人员可以直接调用这些对象的方法。Thymeleaf 提供的内置对象如下表所示。

对象说明
#request可直接替代 HttpServletRequest 对象
#session可直接替代 HttpSession 对象
#aggregates聚合操作工具类
#arrays数组工具类
#bools布尔类型工具类
#calenders日历工具类
#dates日期工具类
#listslist 工具类
#mapsmap 工具类
#numbers数字工具类
#objects一般对象工具类
#setsset 工具类
#strings字符串工具类

注意:
每一个内置对象前都必须有 # 前缀,除了 #request 和 #session,其他对象名称末尾均有小写 s。
内置对象要在 ${} 表达式中使用。

【 示例:读取当前登录的用户名并写入要展示的消息 】

  1. 创建 IndexController 控制器类,在映射方法中添加 HttpServletRequest 和 HttpSession 参数,向 HttpServletRequest 写入要展示的消息,向 HttpSession 写入当前登录的用户名,代码如下:
@Controller
public class IndexController {@RequestMapping("/index")public String index(HttpServletRequest request, HttpSession session) {request.setAttribute("message", "欢迎访问 XXX 网站");session.setAttribute("user", "David");return "index";}
}
  1. 在 index.html 中使用 #session 就可以直接从 HttpSession 中读取用户名,用 #request 直接从 HttpServletRequest 中读取消息,代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head><meta charset="UTF-8">
</head>
<body><p th:text="'您好,' + ${#session.getAttribute('user')}" /><p th:text="${#request.getAttribute('message')}" />
</body>
</html>
  1. 启动项目后,打开浏览器访问 http://127.0.0.1:8080/index 地址,可以看到下图结果,HttpServletRequest 和 HttpSession 中的数据可以正常读出。

在这里插入图片描述

注意:
Thymeleaf 3.0 之前,上面代码是可以运行的,但是 Thymeleaf 3.0 之后,运行会报错:
java.lang.IllegalArgumentException: The ‘request’,‘session’,‘servletContext’ and ‘response’ expression utility objects are no longer available by default for template expressions and their use is not recommended. In cases where they are really needed, they should be manually added as context variables.

从 Thymeleaf 3.0 开始,默认不再支持通过 #request 和 #session 来获取这些对象了。需要手动将这些对象添加到模板上下文中!

  1. 我们修改 IndexController:
@Controller
public class IndexController {@RequestMapping("/index")public String index(HttpServletRequest request, HttpSession session, Model model) {// 使用模型传递数据model.addAttribute("message", "欢迎访问 XXX 网站");model.addAttribute("user",session.getAttribute("user") != null ? session.getAttribute("user") : "David");return "index";}
}
  1. 修改 index.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<body><p th:text="'您好,' + ${user}" /><p th:text="${message}" />
</body>
</html>
  1. 运行看效果:

在这里插入图片描述


七、条件语句

Java 的条件语句有两种:if 判断语句和 switch 分支语句,Thymeleaf 模板引擎也提供了这两种语句,可以显示或隐藏网页中的一些特殊内容。

th:if 是 Thymeleaf 的判断语句,支持下表所示的比较运算符。

在这里插入图片描述

例如,如果后端发送的 num 是 100,就显示“您充值的金额为 100”,前端的代码如下:

​​​​<div th:if="*{num} == 100">
​​​​     <p>您充值的金额为100</p>
​​​​</div>​​

上述代码也可以写成英文替代符号形式:

​​​​<div th:if="*{num} eq 100">
​​​​     <p>您充值的金额为100</p>
​​​​</div>​​

如果后端发送的 num 不等于 100,则不会显示 th:if 标签内的任何内容。

如果 th:if 需要同时判断多个条件,可以使用下表所示的逻辑运算符:

在这里插入图片描述

例如,如果后端发送的 name是张三,并且 age 大于或等于 18,则显示“张三-成年人”,代码如下:

​​​​<div th:if="*{name} == 张三 and age >= 18 ">
​​​​     <p>张三-成年人</p>
​​​​</div>​​

逻辑运算符中没有取反运算,因为 Thymeleaf 使用 th:unless 标签来取 th:if 标签的反结果,相当于 Java 里 else 语句的效果。例如,后端发送的 age 如果大于或等于 18 则显示成年人,小于 18 则显示未成年人,代码如下:

​​​​<div th:if="age >= 18 ">
​​​​     <p>成年人</p>
​​​​</div>
​​​​<div th:unless="age >= 18 ">
​​​​     <p>未成年人</p>
​​​​</div>​​

【 示例:判断某个人是否是成年人 】

  1. 创建 IndexController 控制器类,为映射“/index”的方法添加 Model 参数,分别将该参数的 name(姓名)属性赋值为 “Leon”、age(年龄)属性赋值为 17,最后跳转至 main.html 页面。
@Controller
public class IndexController {@RequestMapping("/index")public String index(Model model) {// 使用模型传递数据model.addAttribute("name", "Leon");model.addAttribute("age", 17);return "main";}
}
  1. 在 main.html 中获取 Model 的 name 和 age 属性,如果姓名不为空,则判断年龄是否小于 18 岁,小于 18 岁则这个人是未成年人,否则这个人是成年人。代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<body><div th:if="*{name}!=null"><p th:text="*{name}" /><p th:if="*{age}<18">未成年人</p><p th:unless="*{age}<18">成年人</p></div>
</body>
</html>
  1. 看下效果:

在这里插入图片描述

除了判断语句,Thymeleaf 还支持 switch 分支语句,需要用到 th:switch 和 th:case 这两个标签,其语法如下:

​​​​<div th:switch="*{属性名}">
​​​​    <div th:case="值1"> </div>
​​​​    <div th:case="值2"> </div>...
​​​​</div>

如果 th:switch 读出的属性值与某个 th:case 的值相等,就会显示该 th:case 标签中的内容。


八、循环语句

虽然 Java 常用的循环语句有 while 循环语句和 for 循环语句,但是 Thymeleaf 中的循环语句既不是 while,也不是 for,而是 th:each。可以把 th:each 理解为遍历、迭代的意思。

th:each 的语法比较特殊,比较像 Java 语言中的 foreach 循环。th:each 只能读取后端发来的队列对象(常用 List 类型),然后遍历队列中的所有元素,每取出一个元素就会将其保存在一个临时的循环变量中,其语法如下:

​​​​<div th:each="临时变量:${队列对象}">
​​​​    <div th:text="${临时变量.属性}"></div>
​​​​    <div th:text="${临时变量.方法())}"></div>
​​​​</div>​​

类似的 foreach 语法如下:

​​​​List list = new ArrayList();
​​​​for (Object o : list) {
​​​​    o.getClass();}

Thymeleaf 可以自动创建一个遍历状态变量,该变量名称为“临时变量名称+Stat”,调用${临时变量Stat.index}可获得遍历的行索引,第一行的索引为 0。例如,遍历人员列表的行索引:

<div th:each="people:${list}">
​​​​    <div th:text="'当前为第' + ${peopleStat.index} + ''"></div>
​​​​</div>​​

【 示例:打印存储在队列里的人员的姓名、年龄和性别 】

  1. 首先创建人员实体类,类中包含姓名、年龄和性别3个属性,同时要包含构造方法和属性的 Getter/ Setter 方法。代码如下:
public class People {private String name;private Integer age;private String sex;public People(String name, int age, String sex) {this.name = name;this.age = age;this.sex = sex;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void setAge(Integer age) {this.age = age;}public Integer getAge() {return age;}public void setSex(String sex) {this.sex = sex;}public String getSex() {return sex;}
}
  1. 然后创建 IndexController 控制器类,创建 4 个 People 对象并保存在 List 队列中,将队列保存在 Model中,跳转至 main.html 页面。IndexController 类的代码如下:
@Controller
public class IndexController {@RequestMapping("/index")public String index(Model model) {List<People> list = new ArrayList<>();list.add(new People("David", 26, "Male"));list.add(new People("Leon", 17, "Male"));list.add(new People("Rose", 21, "Female"));list.add(new People("Steven", 34, "Male"));model.addAttribute("peoples", list);return "main";}
}
  1. 在 main.html 中使用 th:each 标签遍历人员队列,并将每个人员的数据保存在 people 变量中,在页面中打印每个人员的姓名、年龄和性别数据,代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<body><div th:each="people:${peoples}"><a th:text="${peopleStat.index + 1} + ''"></a><a  th:text="',姓名:' + ${people.name}"></a><a  th:text="',年龄:' + ${people.age}"></a><a  th:text="',性别:' + ${people.sex}"></a></div>
</body>
</html>
  1. 运行看效果:

在这里插入图片描述


九、~{} 表达式

很多网站的页面会共用同一个页面内容。例如,网站头部的菜单、网站底部的声明,有些网站还会共用两侧的广告栏。这些被多个页面重复使用的页面板块通常会被单独保存成一个 .html 文件。为了能够把 .html 文件嵌入其他页面中,Thymeleaf 提供了 ~{} 表达式,被插入的片段必须通过 th:fragment 标签定义。

【 示例:在主页插入顶部的登录菜单和底部的声明页面 】

  1. 首先要创建 3 个 .html 文件,index.html 为主页,bottom 文件夹下的 foot.html 为所有网页共用的底部页面,top 文件夹下的 head.html 为所有网页共用的底部页面。3 个文件的位置如图所示:

在这里插入图片描述

  1. 在 head.html 文件中,创建“登录”和“注册”两个超链接,并使用 th:fragment 将最外层的 div 定义为 “login” 代码片段,这样其他页面通过嵌入 “login” 就可以展示此顶部页面。head.html 的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<div th:fragment="login"><div style="float: right"><a href="#">登录</a>&nbsp;&nbsp;<a href="#">注册</a></div>
</div>
</html>
  1. 在 foot.html 文件中,模拟展示一行简易的声明文字,然后将最外层的 div 定义为 “foot” 代码片段,其他页面通过嵌入 “foot” 就可以展示此底部页面。foot.html 的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<div th:fragment="foot"><div style="width: 100%; position: fixed; bottom: 0px; text-align: center;"><p>联系我们 XXXX公司 公安备案XXXXXXXXXX</p></div>
</div>
</html>
  1. 在 index.html 主页文件中,通过 th:include 标签插入刚才写好的顶部和底部。例如:~{top/head::login} 是插入顶部片段的表达式,其含义为:此处插入的代码片段来自 top 目录下的 head.html 文件,代码片段的名称为 login。~{bottom/foot::foot} 同理。th:fragment 标签定义的代码片段是什么,就会在 th:include 内显示什么。index.html 的代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8">
</head>
<body><div th:include="~{top/head::login}"></div><br><br><div style="text-align: center"><h1>欢迎来到 XXX 网站</h1></div><br><br><div th:include="~{bottom/foot::foot}"></div>
</body>
</html>
  1. 编写完所有 .html 文件后,创建一个简单 Controller 类以跳转至主页,代码如下:
@Controller
public class IndexController {@RequestMapping("/index")public String index() {return "index";}
}
  1. 启动查看效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444737.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序-分包加载

一.分包的意义 小程序是由多个页面构成&#xff0c;为了因为代码量多&#xff0c;体积大导致用户打开速度变慢&#xff0c;小程序提供了分包加载数据。 分包加载数据&#xff0c;只有在主包调用分包某一个页面时候才会调用加载分包。即就是按需加载。 整个小程序不能超过20M&a…

golang grpc进阶

protobuf 官方文档 基本数据类型 .proto TypeNotesGo Typedoublefloat64floatfloat32int32使用变长编码&#xff0c;对于负值的效率很低&#xff0c;如果你的域有可能有负值&#xff0c;请使用sint64替代int32uint32使用变长编码uint32uint64使用变长编码uint64sint32使用变长…

滚柱导轨适配技巧与注意事项!

滚柱导轨是一种重要的传动元件&#xff0c;它由滚柱作为滚动体。用于连接机床的运动部件和床身基座&#xff0c;其设计旨在提供高承载能力和高刚度&#xff0c;适用于重型机床和精密仪器&#xff0c;而滚柱导轨的适配方法对于确保机械设备的高精度运行至关重要。 滚柱导轨的适配…

大数据分析案例-基于逻辑回归算法构建抑郁非抑郁推文识别模型

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章 大数据分析案例合集

介绍Java

Java简介 Java是一门由Sun公司&#xff08;现被Oracle收购&#xff09;在1995年开发的计算机编程语言&#xff0c;其主力开发人员是James Gosling&#xff0c;被称为Java之父。Java在被命名为“Java”之前&#xff0c;实际上叫做Oak&#xff0c;这个名字源于James Gosling望向…

Unite Barcelona主题演讲回顾:深入了解 Unity 6

本周&#xff0c;来自世界各地的 Unity 开发者齐聚西班牙巴塞罗那&#xff0c;参加 Unite 2024。本次大会的主题演讲持续了一个多小时&#xff0c;涵盖新功能的介绍、开发者成功案例的分享&#xff0c;以及在编辑器中进行的技术演示&#xff0c;重点展示了 Unity 6 在实际项目中…

学习python自动化——pytest单元测试框架

一、什么是pytest 单元测试框架&#xff0c;unittest&#xff08;python自带的&#xff09;&#xff0c;pytest&#xff08;第三方库&#xff09;。 用于编写测试用例、收集用例、执行用例、生成测试结果文件&#xff08;html、xml&#xff09; 1.1、安装pytest pip instal…

Spring AI 介绍与入门使用 -- 一个Java版Langchain

Langchain 是什么&#xff1f; Langchain 是一个Python 的AI开发框架&#xff0c;它集成了模型输入输出、检索、链式调用、内存记忆&#xff08;Memory&#xff09;、Agents以及回调函数等功能模块。通过这些模块的协同工作&#xff0c;它能够支持复杂的对话场景和任务执行流程…

C语言 | Leetcode C语言题解之第460题LFU缓存

题目&#xff1a; 题解&#xff1a; /* 数值链表的节点定义。 */ typedef struct ValueListNode_s {int key;int value;int counter;struct ValueListNode_s *prev;struct ValueListNode_s *next; } ValueListNode;/* 计数链表的节点定义。 其中&#xff0c;head是数值链表的头…

多点低压差分(M-LVDS)线路驱动器和接收器——MS2111

MS2111 是多点低压差分 (M-LVDS) 线路驱动器和接收器。经过 优化&#xff0c;可运行在高达 200Mbps 的信号速率下。所有部件均符合 M LVDS 标准 TIA / EIA-899 。该驱动器的输出支持负载低至 30Ω 的多 点总线。 MS2111 的接收器属于 Type-2 &#xff0c; 可在 -1…

【GESP】C++一级练习BCQM3037,简单计算,国庆七天乐收官

又回到了简单计算的题目&#xff0c;继续巩固练习。 题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3037/ 【GESP】C一级练习BCQM3037&#xff0c;简单计算&#xff0c;国庆七天乐收官 | OneCoder又回到了简单计算的题目&#xff0c;继续巩固练习。https://www.cod…

性能测试工具locust —— Python脚本参数化!

1.1.登录用户参数化 在测试过程中&#xff0c;经常会涉及到需要用不同的用户登录操作&#xff0c;可以采用队列的方式&#xff0c;对登录的用户进行参数化。如果数据要保证不重复&#xff0c;则取完不再放回&#xff1b;如可以重复&#xff0c;则取出后再返回队列。 def lo…

std::future::then的概念和使用方法

std::future::then是 C 中用于异步操作的一种机制&#xff0c;它允许在一个异步任务完成后&#xff0c;接着执行另一个操作&#xff08;即延续操作&#xff09;。以下是关于 std::future::then 的概念和使用方法&#xff1a; 1. 概念&#xff1a; std::future::then 的主要目…

Chrome清除nslookup解析记录 - 强制http访问 - 如何禁止chrome 强制跳转https

步骤&#xff1a; 地址栏输入 chrome://net-internals/#hsts在Delete domain 栏的输入框中输入要http访问的域名&#xff0c;然后点击“delete”按钮最后在Query domain 栏中搜索刚才输入的域名&#xff0c;点击“query”按钮后如果提示“Not found”即可&#xff01; 办法来自…

Java | Leetcode Java题解之第459题重复的子字符串

题目&#xff1a; 题解&#xff1a; class Solution {public boolean repeatedSubstringPattern(String s) {return kmp(s s, s);}public boolean kmp(String query, String pattern) {int n query.length();int m pattern.length();int[] fail new int[m];Arrays.fill(fa…

Hunuan-DiT代码阅读

一 整体架构 该模型是以SD为基础的文生图模型&#xff0c;具体扩散模型原理参考https://zhouyifan.net/2023/07/07/20230330-diffusion-model/&#xff0c;代码地址https://github.com/Tencent/HunyuanDiT&#xff0c;这里介绍 Full-parameter Training 二 输入数据处理 这里…

E系列I/O模块在锂电装备制造系统的应用

为了满足电池生产线对稳定性和生产效率的严苛要求&#xff0c;ZLG致远电子推出高速I/O应用方案&#xff0c;它不仅稳定可靠&#xff0c;而且速度快&#xff0c;能够迅速响应生产需求。 锂电池的生产工艺较为复杂&#xff0c;大致分为三个主要阶段&#xff1a;极片制作、电芯制作…

单点登录Apereo CAS 7.1客户端集成教程

从上一篇部署并成功运行CAS服务端后,我们已经能通过默认的账号密码进行登录。 上篇地址:单点登录Apereo CAS 7.1安装配置教程-CSDN博客 本篇我们将开始对客户端进行集成。 CAS中的客户端,就是指我们实际开发的各个需要登录认证的应用。现在,跟着笔者的步伐,一起探索如何…

springmvc直接访问 上下文路径 302 后路径更改并跳转源码解析

【问题现状】 application.yml 配置如下属性&#xff1a; server:servlet:context-path: /learning直接访问&#xff1a;http://localhost:8888/learning 路径时&#xff0c;会返回302的响应状态&#xff1b;并跳转路径&#xff1a;http://localhost:8888/learning/ (原路径后…

Docker Overlay2 空间优化

目录 分析优化数据路径规划日志大小限制overlay2 大小限制清理冗余数据 总结 分析 overlay2 目录占用磁盘空间较大的原因通常与 Docker 容器和镜像的存储机制以及它们的长期累积相关&#xff0c;其实我之前在 Docker 原理那里已经提到过了。 通常时以下几种原因导致&#xff…