大型系统一般都是进行前后端分享,但是我对于系统刚刚从零开始或者一些项目、内部项目都没有进行前后端分离。使用的都是模板技术,今天就来分享一下 Spring Boot WebFlux 整合模板引擎 Thymeleaf 的例子。
Thymeleaf是一个现代的服务器端Java模板引擎,适用于web和独立环境。 – 官方文档
1、项目结构
2、项目依赖
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.carlzone.webflux</groupId>
<artifactId>web-flux-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-flux-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、User.java
下面是定义的用户类。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String id;
private String name;
private int age;
}
4、UserController.java
定义用户处理类,包含获取用户列表页面以及用户详情页面。对于列表数据需要使用 ReactiveDataDriverContextVariable
对象进行包装。
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(path = "detail/{id}")
public Mono<String> detail(Model model, @PathVariable String id) {
model.addAttribute("title", "Spring WebFlux + Thymeleaf : Detail");
model.addAttribute("user", genUser(id));
String path = "user/detail";
return Mono.create(monoSink -> monoSink.success(path));
}
@RequestMapping(path = "/list")
public String list(Model model) {
Flux<User> dataStream = genDataStream();
IReactiveDataDriverContextVariable reactiveDataDrivenMode =
new ReactiveDataDriverContextVariable(dataStream,1);
model.addAttribute("title", "Spring WebFlux + Thymeleaf : List");
model.addAttribute("users", reactiveDataDrivenMode);
return "user/list";
}
/**
* 生成单个用户
* @param id
* @return
*/
private User genUser(String id){
return User.builder().id(id).name("liLei").age(25).build();
}
/**
* 生成用户列表
* @return
*/
private Flux<User> genDataStream() {
User carl = User.builder().id("1").name("carl").age(31).build();
User bob = User.builder().id("2").name("bob").age(18).build();
Flux<User> dataStream = Flux.fromIterable(Lists.newArrayList(carl, bob));
return dataStream;
}
}
5、detail.html
用户详情模板页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div id="title">
<h1 th:text="${title}">Title</h1>
</div>
<table id="allUsers" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td>[[${user.age}]]</td>
</tr>
</tbody>
</table>
</body>
</html>
6、list.html
用户列表模板页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div id="title">
<h1 th:text="${title}">Title</h1>
</div>
<table id="allUsers" class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr data-th-each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td>[[${user.age}]]</td>
</tr>
</tbody>
</table>
</body>
</html>
7、测试请求
在浏览器请求:http:localhost:8080/user/detail/1
在浏览器请求:http://localhost:8080/user/list