Hướng dẫn sử dụng Spring Boot và Thymeleaf

Xem thêm các chuyên mục:

1- Thymeleaf là gì?

Thymeleaf là một Java XML/XHTML/HTML5 Template Engine nó có thể làm việc với cả hai môi trường Web và môi trường không phải Web. Nó phù hợp hơn khi được sử dụng để phục vụ XHTML/HTML5 trên tầng View (View Layer) của ứng dụng Web dựa trên kiến trúc MVC. Nó có thể xử lý bất kỳ một file XML nào, thậm trí trên các môi trường offline (Không trực tuyến). Nó hỗ trợ đầy đủ để tương tác với Spring Framework.
Các file mẫu (Template file) của Thymeleaf bản chất chỉ là một file văn bản thông thường, có định dạng XML/XHTML/HTML5. Thymeleaf Engine (Bộ máy Thymeleaf) sẽ đọc một file mẫu (template file) và kết hợp với các đối tượng Java để tạo ra (generate) một tài liệu khác.
Thymeleaf có thể sử dụng để thay thế cho JSP trên tầng View (View Layer) của ứng dụng Web MVC. Thymeleaf là phần mềm mã nguồn mở, được cấp phép theo giấy phép Apache 2.0.
Dưới đây là hình ảnh của ứng dụng mà chúng ta sẽ thực hiện trong bài học này:

2- Tạo ứng dụng

Trên Eclipse chọn:
  • File/New/Other...
Nhập vào:
  • Name: SpringBootThymeleaf
  • Group: org.o7planning
  • Artifact: SpringBootThymeleaf
  • Description: Spring Boot and Thymeleaf
  • Package: org.o7planning.thymeleaf
Lựa chọn 2 công nghệ Web Thymeleaf.
Project của bạn đã được tạo ra:

3- Thymeleaf Template

Thymeleaf Template là các file mẫu. Nội dung của nó theo định dạng XML/XHTML/HTML5. Chúng ta sẽ tạo ra 3 file và đặt tại thư mục src/main/resources/templates:
index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
   <head>
      <meta charset="UTF-8" />
      <title>Welcome</title>
      <link rel="stylesheet" type="text/css" th:href="@{/css/style.css}"/>
   </head>
   <body>
      <h1>Welcome</h1>
      <h2 th:utext="${message}">..!..</h2>
      
      <!--  
      
         In Thymeleaf the equivalent of
         JSP's ${pageContext.request.contextPath}/edit.html
         would be @{/edit.html}
         
         -->
         
      <a th:href="@{/personList}">Person List</a>  
      
   </body>
   
</html>
 
personList.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
   <head>
      <meta charset="UTF-8" />
      <title>Person List</title>
      <link rel="stylesheet" type="text/css" th:href="@{/css/style.css}"/>
   </head>
   <body>
      <h1>Person List</h1>
      <a href="addPerson">Add Person</a>
      <br/><br/>
      <div>
         <table border="1">
            <tr>
               <th>First Name</th>
               <th>Last Name</th>
            </tr>
            <tr th:each ="person : ${persons}">
               <td th:utext="${person.firstName}">...</td>
               <td th:utext="${person.lastName}">...</td>
            </tr>
         </table>
      </div>
   </body>
</html>
 
addPerson.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
   <head>
      <meta charset="UTF-8" />
      <title>Add Person</title>
      <link rel="stylesheet" type="text/css" th:href="@{/css/style.css}"/>
   </head>
   <body>
      <h1>Create a Person:</h1>
      
      <!--  
         In Thymeleaf the equivalent of
         JSP's ${pageContext.request.contextPath}/edit.html
         would be @{/edit.html}         
         -->
         
      <form th:action="@{/addPerson}"
         th:object="${personForm}" method="POST">
         First Name:
         <input type="text" th:field="*{firstName}" />    
         <br/>
         Last Name:
         <input type="text" th:field="*{lastName}" />     
         <br/>
         <input type="submit" value="Create" />
      </form>
      
      <br/>
      
      <!-- Check if errorMessage is not null and not empty -->
      
      <div th:if="${errorMessage}" th:utext="${errorMessage}"
         style="color:red;font-style:italic;">
         ...
      </div>
      
   </body>
</html>
Ở trên tôi đã tạo ra 3 file HTML. Các file HTML ở trên cần phải phù hợp với các tiêu chuẩn của XML, tất cả các thẻ (tag) đều phải có mở và đóng. Chẳng hạn:
<div>A div tag</div>

<br />

<meta charset="UTF-8" />
Tất cả các file HTML cần phải khai báo sử dụng Thymeleaf Namespace:
<!-- Thymeleaf Namespace -->

<html xmlns:th="http://www.thymeleaf.org">
Trong các file mẫu (Template file) có các Thymeleaf Marker (Các đánh dấu của Thymeleaf), chúng là các chỉ dẫn giúp Thymeleaf Engine chế biến dữ liệu.
Thymeleaf Engine phân tích file mẫu (Template file), và kết hợp với các dữ liệu Java để tạo ra (generate) một tài liệu mới.
Dưới đây là các ví dụ để sử dụng Context-Path trong Thymeleaf:
<!-- Example 1:  -->

<a th:href="@{/mypath/abc.html}">A Link</a>

Output: ==>

<a href="/my-context-path/mypath/abc.html">A Link</a>


<!-- Example 2:  -->

<form th:action="@{/mypath/abc.html}"
          th:object="${personForm}" method="POST">

Output: ==>

<form action="/my-context-path/mypath/abc.html"  method="POST">
 

4- Static Resource & Properties File

Với các nguồn dữ liệu tĩnh (Static Resource), chẳng hạn các file css, javascript, image,.. bạn cần đặt chúng vào thư mục src/main/resources/static hoặc các thư mục con của nó.
style.css
h1 {
    color:#0000FF;
}

h2 {
    color:#FF0000;
}

table {
    border-collapse: collapse;
}

table th, table td {
    padding: 5px;
}
application.properties

welcome.message=Hello Thymeleaf
error.message=First Name & Last Name is required!

5- Các lớp Model, Form, Controller

Person.java
package org.o7planning.thymeleaf.model;

public class Person {

    private String firstName;
    private String lastName;

    public Person() {

    }

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}
Lớp PersonForm đại diện cho dữ liệu của FORM khi bạn tạo mới một Person trên trang addPerson.
PersonForm.java
package org.o7planning.thymeleaf.form;
 

public class PersonForm {

    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    
}
MainController là một lớp Controller, nó xử lý yêu cầu của người dùng và điều khiển luồng đi (flow) của ứng dụng.
MainController.java
package org.o7planning.thymeleaf.controller;

import java.util.ArrayList;
import java.util.List;

import org.o7planning.thymeleaf.form.PersonForm;
import org.o7planning.thymeleaf.model.Person;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MainController {

	private static List<Person> persons = new ArrayList<Person>();

	static {
		persons.add(new Person("Bill", "Gates"));
		persons.add(new Person("Steve", "Jobs"));
	}

	// Được tiêm vào (inject) từ application.properties.
	@Value("${welcome.message}")
	private String message;

	@Value("${error.message}")
	private String errorMessage;

	@RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
	public String index(Model model) {

		model.addAttribute("message", message);

		return "index";
	}

	@RequestMapping(value = { "/personList" }, method = RequestMethod.GET)
	public String personList(Model model) {

		model.addAttribute("persons", persons);

		return "personList";
	}

	@RequestMapping(value = { "/addPerson" }, method = RequestMethod.GET)
	public String showAddPersonPage(Model model) {

		PersonForm personForm = new PersonForm();
		model.addAttribute("personForm", personForm);

		return "addPerson";
	}

	@RequestMapping(value = { "/addPerson" }, method = RequestMethod.POST)
	public String savePerson(Model model, //
			@ModelAttribute("personForm") PersonForm personForm) {

		String firstName = personForm.getFirstName();
		String lastName = personForm.getLastName();

		if (firstName != null && firstName.length() > 0 //
				&& lastName != null && lastName.length() > 0) {
			Person newPerson = new Person(firstName, lastName);
			persons.add(newPerson);

			return "redirect:/personList";
		}

		model.addAttribute("errorMessage", errorMessage);
		return "addPerson";
	}

}

6- Chạy ứng dụng

Để chạy ứng dụng, nhấn phải chuột vào Project chọn:
  • Run As/Spring Boot App.
Ứng dụng đã được triển khai (deploy) trên một Embedded Web Server.
Chạy URL sau trên trình duyệt:

Xem thêm các chuyên mục: