Spring Boot 構建企業級部落格學習(四)- Spting Boot 整合Thymeleaf模板
阿新 • • 發佈:2019-01-08
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>