版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_35367612/article/details/81219257
Spting Boot 集成Thymeleaf模板
- 理解Thymeleaf的概念、用法
- Thymeleaf 与 Spring Boot 集成
- Thymeleaf 实战
Thymeleaf概念
理解Thymeleaf
- Thymeleaf是一种java的模板引擎,支持html、xml、javascript、css甚至是纯文本。类似jsp和Freemarker。
- 自然模板。遵循高度可维护原则,原型即页面。
- 语法优雅易懂。使用OGNL、SpringEL,和spring集成很好
- 遵循web标准,支持html5
Thymeleaf标准方言展示形式
展示形式
. <span th:text="...">
. <span data-th-text="">
1.变量表达式
语法:${...}
<span th:text="book.author.name">
2.消息表达式
语法:#{...}
<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
也称作文本外部化、国际化或i18n
3.选择表达式
语法:*{...}
<div th:object="${book}">
...
<span th:text="*{title}"></span>
...
</div>
.与变量表达式的区别:他们是在当前对象而不是在上下文变量映射上执行
4.链接表达式
语法:@{...}
5.分段表达式
语法:th:insert 或 th:replace
引用 th:fragment 定义的代码片段
6.字变量
.文字 th:text="'文字'" //文字需要用单引号
.数字 th:text="2018+1"
.布尔 th:if="${book.isYes} == true"
.null th:if="${book.title} == null"
7.算数操作
比较 >、<、>=、<=(gt、lt、ge、le)
等价 ==、!=(eq、ne)
8.条件运算符
th:text="${obj}? : "
9.无操作 _
th:text="${obj}? : _"
10.迭代器
语法:th:each
状态变量 index、count、size、current、even/old
11.条件语句
语法:th:if th:unless
th:switch th:case
Thymeleaf 实战
api设计
Thymeleaf集成 Spring Boot
- 修改gradle.build文件修改依赖
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
-
修改thymeleaf版本
buildscript { ... ext['thymeleaf.version']='3.0.0.RELEASE' ext['thymeleaf-layout-dialect.version']='2.2.0' ... }
3.
使用Thymeleaf编写简单的增删改查
用户实体类
package com.spring.boot.thymeleaf.blog.model;
/**
* 用户试题类
* @author hemin
*/
public class User {
private Long id;
private String name;
private String email;
public User() {
super();
}
public User(Long id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UserRepository.java
package com.spring.boot.thymeleaf.blog.repository;
import java.util.List;
import com.spring.boot.thymeleaf.blog.model.User;
public interface UserRepository {
User saveOrUpdate(User user);
List<User> list();
User getById(Long id);
void delete(Long id);
}
UserRepositoryImpl.java
使用AtomicLong进行id的自增
使用ConcurrentMap存储数据 ,代替关系型数据库
package com.spring.boot.thymeleaf.blog.repository.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Repository;
import com.spring.boot.thymeleaf.blog.model.User;
import com.spring.boot.thymeleaf.blog.repository.UserRepository;
@Repository
public class UserRepositoryImpl implements UserRepository {
private final ConcurrentMap<Long, User> map = new ConcurrentHashMap<>();
private static AtomicLong atomicLong = new AtomicLong();
@Override
public User saveOrUpdate(User user) {
if(user.getId()==null) {
user.setId(atomicLong.incrementAndGet());
}
return map.put(user.getId(),user);
}
@Override
public List<User> list() {
return new ArrayList<User>(map.values());
}
@Override
public User getById(Long id) {
return map.get(id);
}
@Override
public void delete(Long id) {
map.remove(id);
}
}
UserController
package com.spring.boot.thymeleaf.blog.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.spring.boot.thymeleaf.blog.model.User;
import com.spring.boot.thymeleaf.blog.repository.UserRepository;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
UserRepository userRepository;
/**
* s查询所有用户
* @param model
* @return
*/
@GetMapping
public ModelAndView userAll(Model model) {
model.addAttribute("userList", userRepository.list());
model.addAttribute("title", "用户列表");
return new ModelAndView("users/list","userModel",model);
}
/**
* s根据id查询用户
* @param model
* @return
*/
@GetMapping("/{id}")
public ModelAndView view(@PathVariable(value="id") Long id,Model model) {
model.addAttribute("user", userRepository.getById(id));
model.addAttribute("title", "用户信息");
return new ModelAndView("users/view","userModel",model);
}
/**
* s跳转到添加和修改页面
* @param model
* @return
*/
@GetMapping("/form")
public ModelAndView toForm(Model model) {
model.addAttribute("user",new User());
return new ModelAndView("users/form","userModel",model);
}
/**
* s完成添加或修改操作,完成后重定向到list页面
* @param model
* @return
*/
@PostMapping
public ModelAndView saveOrUpdate(User user,Model model) {
userRepository.saveOrUpdate(user);
return new ModelAndView("redirect:/users","userModel",model);
}
/**
* s完成添加或修改操作,完成后重定向到list页面
* @param model
* @return
*/
@GetMapping("/delete/{id}")
public ModelAndView deletre(@PathVariable(value="id") Long id) {
userRepository.delete(id);
return new ModelAndView("redirect:/users");
}
/**
* s获取信息,跳转到修改页面
* @param model
* @return
*/
@GetMapping("/update/{id}")
public ModelAndView update(@PathVariable(value="id") Long id,Model model) {
model.addAttribute("user",userRepository.getById(id));
return new ModelAndView("users/form","userModel",model);
}
}
header.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Thymeleaf in action</title>
</head>
<body>
<div data-th-fragment="header">
<h1>Thymeleaf in action</h1>
<a href="/users">回到首页</a>
</div>
</body>
</html>
footer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Thymeleaf in action</title>
</head>
<body>
<div data-th-fragment="footer" style="position: fixed;bottom: 150px">
<a href="http://www.imooc.com">学习</a>
</div>
</body>
</html>
list.html
首先引入thymeleaf依赖
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<a href="/users/form">新增</a>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>邮箱</td>
<td>姓名</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">没有用户信息!</td>
</tr>
<tr th:each="user : ${userModel.userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.email}"></td>
<td>
<a th:text="${user.name}" th:href="@{'/users/' + ${user.id}}"></a>
</td>
</tr>
</tbody>
</tbody>
</table>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
form.html 添加和修改页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<div>
<form action="/users" th:action="@{~/users}" method="post">
<input type="text" name="id" th:value="${userModel.user.id}" hidden />
<table>
<tr>
<td>用户名:<td>
<td><input type="text" name="name" th:value="${userModel.user.name}"><td>
<tr>
<tr>
<td>邮箱:<td>
<td><input type="text" name="email" th:value="${userModel.user.email}"><td>
<tr>
</table>
<input type="submit" value="提交">
</form>
</div>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
view.html 个人详情页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<div th:object="${userModel.user}">
<p><strong>id:</strong><span th:text="*{id}"></span></p>
<p><strong>email:</strong><span th:text="*{email}"></span></p>
<p><strong>name:</strong><span th:text="*{name}"></span></p>
</div>
<div>
<a th:href="@{'~/users/delete/' + ${userModel.user.id}}">删除</a>
<a th:href="@{'~/users/update/' + ${userModel.user.id}}">修改</a>
</div>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>