1. 程式人生 > >Spring Boot 構建企業級部落格學習(四)- Spting Boot 整合Thymeleaf模板

Spring Boot 構建企業級部落格學習(四)- Spting Boot 整合Thymeleaf模板

Spting Boot 整合Thymeleaf模板 

  • 理解Thymeleaf的概念、用法
  • Thymeleaf 與 Spring Boot 整合
  • Thymeleaf 實戰

Thymeleaf概念

理解Thymeleaf

  1. Thymeleaf是一種java的模板引擎,支援html、xml、javascript、css甚至是純文字。類似jsp和Freemarker。
  2. 自然模板。遵循高度可維護原則,原型即頁面。
  3. 語法優雅易懂。使用OGNL、SpringEL,和spring整合很好
  4. 遵循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

  1. 修改gradle.build檔案修改依賴
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
  2. 修改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>