Series Spring Boot: Spring Boot 0: Làm chủ Spring Boot, Zero to HeroSeries Spring Boot từ con số 0

Series Spring Core: tại đây

Dưới đây là Series Spring Thymeleaf

  1. Thymeleaf là gì? So sánh JSP, JSF với Thymeleaf
  2. Code ví dụ Spring MVC Thymeleaf Hello – dùng XML config
  3. Code ví dụ Spring MVC Thymeleaf Hello – dùng annotation config
  4. Submit form với Thymeleaf, Code ví dụ Spring Thymeleaf Form
  5. Code ví dụ hiển thị List, Set, Map với Thymeleaf
  6. Code ví dụ đa ngôn ngữ với Thymeleaf Internationalization / i18n
  7. Code ví dụ gửi email – gmail với Thymeleaf + Spring

Ở ví dụ này mình dùng:

  • Spring 5.0.2.RELEASE
  • Thymeleaf 3.0.9.RELEASE

Tạo Maven Project

Thư viện sử dụng

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stackjava.com</groupId>
<artifactId>SpringThymeleaf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
</dependencies>
</project>

File web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">
  <display-name>SpringThymeleaf</display-name>
  <servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring-mvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

File Spring config:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
  <context:component-scan base-package="stackjava.com.springthymeleaf" />
  <bean id="templateResolver"
    class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/templates/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="cacheable" value="false" />
  </bean>
  <bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
  </bean>
  <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
  </bean>
</beans>
  • Bean templateResolver thực hiện thiết lập các thông tin prefix, suffix để chỉ dẫn folder chứa các page view bên trong  thư mục webapp.
  • ThymeleafViewResolver sẽ thực hiện mapping giữa các file view với view name trả về từ controller, ví dụ trong controller trả về “index” thì nó sẽ hiểu là trả về file index.html trong folder /WEB-INF/templates.

Tương tự như chúng ta vẫn thực hiện mapping các file jsp trong Spring MVC:

<bean
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix">
    <value>/WEB-INF/views/jsp/</value>
  </property>
  <property name="suffix">
    <value>.jsp</value>
  </property>
</bean>
  • Thuộc tính cacheable trong bean templateResolver đánh dấu cache cho view, nếu bạn để là true thì hệ thống sẽ lấy file view ban đầu và lưu cache, mọi thay đổi của file view sẽ không được load lên mà phải restart lại server.
  • org.thymeleaf.spring5.view.ThymeleafViewResolver thực hiện xử lý các file html (đọc, hỗ trợ các thẻ html mà thymeleaf cung cấp)

File controller:

package stackjava.com.springthymeleaf.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
  @RequestMapping("/")
  public String index(final Model model) {
    model.addAttribute("message", "hello");
    return "index";
  }
}

File view:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring MVC + Thymeleaf</title>
</head>
<body>
  <h1>Hello: Spring MVC + Thymeleaf</h1>
    <p th:text="'message: ' + ${message} + '!'" />
</body>
</html>

Lưu ý: nhớ khai báo name space: xmlns:th="http://www.thymeleaf.org" trong thẻ html để trình ide hiểu được các thẻ th.

Thẻ th:text="'message: ' + ${message} + '!'"  được coi như 1 thẻ html

Nếu bạn mở trực tiếp file index.html thì thẻ th sẽ không có ý nghĩa và sẽ bị bỏ qua (vì thẻ th không có trong ngôn ngữ html)

Nếu bạn chạy file index.html trên server thì template engine sẽ convert thẻ th sang thẻ html và các giá trị tương ứng

Demo
Trường hợp mở file trực tiếp trên trình duyệt

Code ví dụ Spring MVC Thymeleaf Hello - dùng XML config

Trường hợp chạy server, thẻ th và giá trị message được generate ra giá trị tương ứng.

Code ví dụ Spring MVC Thymeleaf Hello - dùng XML config


Okay, Done!

Download code ví dụ trên tại đây


Loạt bài chủ đề Java trên trang stackjava.com bản quyền thuộc thầy Trần Hữu Cương. Bài viết đăng trên blog Techmaster được sự đồng ý của tác giả.

Thầy Trần Hữu Cương đã và đang tham gia giảng dạy tại Techmater khoá Lộ trình Java Spring Boot Full Stack

Link gốc bài viết tại đây.