0% found this document useful (0 votes)
2 views38 pages

677c9fe402c2ab427298a47e Chapter06-Spring Web Development Thymeleaf

The document provides an overview of Spring Web Development focusing on the Thymeleaf template engine, which is used for creating web applications with Spring Boot. It covers various template modes, configuration, and standard expression syntax in Thymeleaf, detailing how to work with data models and create dynamic content. Additionally, it explains the integration of Thymeleaf with Spring MVC, including the use of expressions for variables, messages, URLs, and conditional statements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views38 pages

677c9fe402c2ab427298a47e Chapter06-Spring Web Development Thymeleaf

The document provides an overview of Spring Web Development focusing on the Thymeleaf template engine, which is used for creating web applications with Spring Boot. It covers various template modes, configuration, and standard expression syntax in Thymeleaf, detailing how to work with data models and create dynamic content. Additionally, it explains the integration of Thymeleaf with Spring MVC, including the use of expressions for variables, messages, URLs, and conditional statements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 38

Spring Web Development

Objectives
◆ Understand a modern server-side Java template engine -Thymeleaf. It is used
for both web and standalone environments, capable of processing HTML, XML,
JavaScript, CSS and even plain text
◆ Building web applications using the Spring Framework on Spring Boot.
 Spring Data JPA + Spring MVC (Model-View-Controller) + Thymeleaf

2
Spring View Technologies
◆ Spring MVC application are cleanly separated switching from one view
technology to another is primarily a matter of configuration.
◆ To render each view type, we define a ViewResolver bean corresponding to
each technology then return the view names from @Controller mapping
methods in the same way
◆ Templating engines
 Thymeleaf
 Java Server Pages (JSP)
 Freemaker

3
What is Thymeleaf?
◆ Thymeleaf is a Java template engine which can process HTML, XML, text,
JavaScript or CSS files. Unlike other template engines, Thymeleaf allows using
templates as prototypes, meaning they can be viewed as static files.
◆ A modern server-side Java template engine for both web and standalone
environments
◆ Main goal is to provide an elegant and highly-maintainable way of creating
templates.
◆ Improves communication of design and bridges the gap between design and
development teams.
◆ Also been designed from the beginning with Web Standards in mind - especially
HTML5 - allowing you to create fully validating templates if that is a need for you
4
Kinds of templates in Thymeleaf
◆ There are two markup template modes (HTML and XML), three textual
template modes (TEXT , JAVASCRIPT and CSS) and a no-op template mode
(RAW).
◆ HTML template mode will allow any kind of HTML input, including HTML5,
HTML 4 and XHTML. No validation or well-formedness check will be
performed, and template code/structure will be respected to the biggest
possible extent in output.
◆ XML template mode will allow XML input. In this case, code is expected to be
well-formed – no unclosed tags, no unquoted attributes, etc – and the parser
will throw exceptions if well-formedness violations are found. Note that no
validation (against a DTD or XML Schema) will be performed.
5
Kinds of templates in Thymeleaf
◆ TEXT template mode will allow the use of a special syntax for templates of a
non-markup nature.
 Examples of such templates might be text emails or templated documentation.
 Note that HTML or XML templates can be also processed as TEXT , in which case they
will not be parsed as markup, and every tag, DOCTYPE, comment, etc, will be treated
as mere text.
◆ JAVASCRIPT template mode will allow
 Processing of JavaScript files in a Thymeleaf application. This means being able to use
model data inside JavaScript files in the same way it can be done in HTML files, but
with JavaScript-specific integrations such as specialized escaping or natural scripting.
 This mode is considered a textual mode and therefore uses the same special syntax as
the TEXT template mode.

6
Kinds of templates in Thymeleaf
◆ CSS template mode will allow the processing of CSS files involved in a
Thymeleaf application.
 Similar to the JAVASCRIPT mode, the CSS template mode is also a textual mode and
uses the special processing syntax from the TEXT template mode.

◆ RAW template mode will simply not process templates at all. It is meant to be
used for inserting untouched resources (files, URL responses, etc.) into the
templates being processed.
 For example, external, uncontrolled resources in HTML format could be included into
application templates, safely knowing that any Thymeleaf code that these resources
might include will not be executed.

7
Configuration Thymeleaf in Spring Boot
◆ Maven Dependencies
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>

◆ Dependencies in Spring Boot


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.6</version>
</dependency>

8
Template folders
◆ In Spring Boot project in Intellij
 Thymeleaf templates will placed in \\resources\templates

◆ In Web application
 Thymeleaf templates will placed by default in WEB-INF/templates

9
Standard Expression Syntax
◆ Simple expressions:
 Variable Expressions: ${...}
 Selection Variable Expressions: *{...}
 Message Expressions: #{...}
 Link URL Expressions: @{...}
 Fragment Expressions: ~{...}
◆ Literals
 Text literals: 'one text' , 'Another one!' ,…
 Number literals: 0 , 34 , 3.0 , 12.3 ,…
 Boolean literals: true , false
 Null literal: null
 Literal tokens: one , sometext , main ,…

10
${} In Thymeleaf
${} được dùng để lấy giá trị từ Model được truyền từ Controller.
@Controller <!DOCTYPE html>
public class HomeController { <html xmlns:th="http://www.thymeleaf.org">
@GetMapping("/home") <head>
public String home(Model model) { <title>Thymeleaf Example</title>
model.addAttribute("username", "JohnDoe"); // Thêm biến vào </head>
Model <body>
model.addAttribute("age", 25); <h1>Welcome, <span th:text="${username}"></span>!</h1>
return "home"; // Trả về file home.html <p>Your age is: <span th:text="${age}"></span></p>
} </body>
} </html>

◆ ${username} → Lấy giá trị của biến username trong Model ("JohnDoe")
◆ ${age} → Lấy giá trị của biến age trong Model (25)
◆ th:text → Gán giá trị vào thẻ HTML (tránh XSS).

11
*{} In Thymeleaf
• *{} được gọi là biểu thức lựa chọn (Selection Expression).
• Nó giúp rút gọn cú pháp truy cập thuộc tính của một đối tượng khi sử dụng
trong thẻ có th:object
@Controller
public class User {
public class UserController {
private String name;
@GetMapping("/user")
private int age;
public String userPage(Model model) {
User user = new User("Alice", 30);
// Constructors, Getters & Setters
model.addAttribute("user", user); // Truyền đối tượng User vào Model
public User(String name, int age) {
return "user";
this.name = name;
}
this.age = age; <!DOCTYPE html>
}
} <html xmlns:th="http://www.thymeleaf.org">
public String getName() { return name; } <head>
public int getAge() { return age; } <title>User Page</title>
} </head>
<body>
◆ th:object="${user}" → Định nghĩa user là đối tượng mặc định <div th:object="${user}"> <!-- Đặt user làm đối tượng hiện tại -->
trong phạm vi thẻ <div>. <h1>Hello, <span th:text="*{name}"></span>!</h1>
<p>Your age is: <span th:text="*{age}"></span></p>
◆ *{name} → Tự động hiểu là user.name. </div>
</body>
</html> 12
#{ } In Thymeleaf
• #{} được gọi là biểu thức thông báo (Message Expression).
• Nó được sử dụng để lấy giá trị từ file i18n (quốc tế hóa - localization), giúp hiển thị nội dung đa ngôn ngữ
trong ứng dụng.
• #{key} sẽ lấy giá trị tương ứng với key trong file messages.properties.
Bước 1: Tạo file i18n (messages.properties)
Thêm thư mục src/main/resources/messages.properties và thêm nội dung:
app.title=Welcome to Thymeleaf!
Bước 3: Sử dụng #{} trong Thymeleaf
user.greeting=Hello, {0}! You are {1} years old. <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
Bước 2: Cấu hình i18n trong <title th:text="#{app.title}"></title> <!-- Lấy giá trị từ messages.properties
-->
application.properties (nếu cần) </head>
spring.messages.basename=messages <body>
spring.messages.encoding=UTF-8 <h1 th:text="#{app.title}"></h1> <!-- Hiển thị: Welcome to Thymeleaf! -->

<p th:text="#{user.greeting(${username}, ${age})}"></p>



#{app.title} → Lấy giá trị từ messages.properties, thay thế bằng "Welcome to <!-- Kết quả: Hello, Alice! You are 30 years old. -->
Thymeleaf!“ </body>
◆ #{user.greeting(${username}, ${age})} </html>
13
@{ } In Thymeleaf
◆ @{} được gọi là biểu thức URL (Link Expression).
◆ Nó dùng để tạo đường dẫn URL động trong các thuộc tính như href, src,
action, giúp quản lý đường dẫn một cách linh hoạt.
• Tạo đường dẫn tĩnh
<a th:href="@{/about}">About Us</a>

• Đường dẫn với tham số


<a th:href="@{/user/profile(id=${userId})}">Profile</a> <a href="/user/profile?id=10">Profile</a>

• Đường dẫn với nhiều tham số


<a th:href="@{/search(keyword=${keyword}, page=${page})}">Search</a>
<a href="/search?keyword=thymeleaf&page=2">Search</a>
14
@{ } In Thymeleaf
• Sử dụng trong form (th:action)

<form th:action="@{/user/save}" method="post"> <form action="/user/save" method="post">


<input type="text" name="name">
<button type="submit">Save</button>
</form>
• Đường dẫn đến tài nguyên (CSS, JS, Images)
<link rel="stylesheet" th:href="@{/css/style.css}"> <link rel="stylesheet"
<script th:src="@{/js/script.js}"></script> href="/css/style.css">
<img th:src="@{/images/logo.png}" alt="Logo"> <script src="/js/script.js"></script>
<img src="/images/logo.png" alt="Logo">

15
Standard Expression Syntax
◆ Text operations:
 String concatenation: +
 Literal substitutions: |The name is ${name}|
◆ Arithmetic operations:
 Binary operators: + , - , * , / , %
 Minus sign (unary operator): -
◆ Boolean operations:
 Binary operators: and , or
 Boolean negation (unary operator): ! , not

<p th:if="${role == 'admin' or role == 'editor'}">✅ Bạn có quyền chỉnh sửa nội dung.</p>
<p th:if="${role == 'user'}">❌ Bạn chỉ có quyền xem.</p>

16
Standard Expression Syntax
◆ Comparisons and equality:
 Comparators: > , < , >= , <= ( gt , lt , ge , le )
 Equality operators: == , != ( eq , ne )
◆ Conditional operators:
 If-then: (if) ? (then)
 If-then-else: (if) ? (then) : (else)
◆ Default: (value) ?: (defaultvalue)
◆ Special tokens:
 No-Operation: _
<p th:class="${status == 'delivered'} ? 'text-success'">Đơn hàng đã
giao</p>
p th:text="${status == 'shipped'} ? '📦 Đơn hàng đã gửi' : '⏳ Đang chờ xử lý'"></p>

17
The Standard Dialect in Thymeleaf
◆ Thymeleaf’s core library provides a dialect called the Standard Dialect, which
should be enough for most users.
◆ Default set of attributes (th:*) that provide powerful templating features. It
allows dynamic content rendering, loops, conditional statements, form handling,
and more within HTML templates.

18
Key Features of The Standard Dialect

19
th:object in Thymeleaf
◆ th:object là một thuộc tính trong Thymeleaf giúp thiết lập một đối tượng làm
phạm vi mặc định trong một phần tử HTML. Điều này giúp rút gọn cú pháp khi
truy cập thuộc tính của đối tượng.
Thay vì viết:
<div th:object="${user}">
<p th:text="${user.name}"></p> <p th:text="*{name}"></p>
<p th:text="${user.age}"></p> <p th:text="*{age}"></p>
</div>

20
th:field in Thymeleaf
public class User {
• Handling Forms with th:field private String name;
private int age;
@Controller
public class UserController { public User() {}
@GetMapping("/form") public User(String name, int age) {
public String showForm(Model model) { this.name = name;
model.addAttribute("user", new User()); this.age = age;
return "form"; }
} // Getters and Setters
}
@PostMapping("/submit") <form th:action="@{/submit}" th:object="${user}" method="post">
public String submitForm(@ModelAttribute User user, Model model) { <label>Name:</label>
model.addAttribute("user", user); <input type="text" th:field="*{name}" />
return "result";
} <label>Age:</label>
} <input type="number" th:field="*{age}" />

<button type="submit">Submit</button>
</form>

21
th:if, th:unless, th:href in Thymeleaf
• Using Conditional Statements (th:if, th:unless)
<p th:if="${user.age >= 18}">You are an adult.</p>
<p th:unless="${user.age >= 18}">You are underage.</p>

• Dynamic Links with th:href


@Controller
public class LinkController { <a th:href="${link}">Go to Google</a>
@GetMapping("/links")
public String showLinks(Model model) {
model.addAttribute("link", "https://www.google.com");
return "links";
}
}

22
th:text in Thymeleaf
◆ th:text là một thuộc tính của Thymeleaf dùng để gán nội dung văn bản
cho một phần tử HTML dựa trên dữ liệu từ model trong Spring Boot
<p th:text="'Hello, ' + ${name} + '!'"></p>
public class User {
private String name;
private int age;
@Controller
public class UserController { public User(String name, int age) {
@GetMapping("/user") this.name = name;
this.age = age;
public String userPage(Model model) { }
User user = new User("Alice", 30); public String getName() { return name; }
model.addAttribute("user", user); public int getAge() { return age; }
return "user"; }
}
} <p>Name: <span th:text="${user.name}"></span></p>
<p>Age: <span th:text="${user.age}"></span></p>

23
th:each in Thymeleaf
◆ Lặp qua danh sách đơn giản
@Controller
public class UserController {
<ul>
@GetMapping("/users")
<li th:each="user : ${users}" th:text="${user}"></li>
public String usersPage(Model model) { </ul>
List<String> users = List.of("Alice", "Bob", "Charlie");
model.addAttribute("users", users);
return "users";
}
}

• Sử dụng biến đếm trong th:each


<tr th:each="user, status : ${users}">
<td th:text="${status.index + 1}"></td> <!-- Bắt đầu từ 0 -->
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
</tr>

24
th:each in Thymeleaf
◆ Lặp qua danh sách đối tượng
public class User { @Controller <table border="1">
private String name; public class UserController { <tr>
private int age; @GetMapping("/users") <th>Name</th>
public String usersPage(Model <th>Age</th>
// Constructor, Getters & Setters model) { </tr>
public User(String name, int age) List<User> users = List.of( <tr th:each="user : ${users}">
{ new User("Alice", 30), <td th:text="${user.name}"></td>
this.name = name; new User("Bob", 25), <td th:text="${user.age}"></td>
this.age = age; new User("Charlie", 35) </tr>
} ); </table>
public String getName() { return model.addAttribute("users", users);
name; } return "users";
public int getAge() { return age; } }
} }

25
th:value in Thymeleaf
◆ th:value là một thuộc tính của Thymeleaf được sử dụng để gán giá trị cho
thẻ <input>, giúp hiển thị dữ liệu mặc định hoặc giá trị từ model khi tải
trang.
@Controller <input type="text" th:value="'Alice'" />
public class UserController {
@GetMapping("/edit")
public String editPage(Model model) {
model.addAttribute("name", "Alice");
return "edit";
} <input type="text" th:value="${name}" />
}

26
th:switch/case in Thymeleaf
Controller (Java)
@Controller
public class UserController {
@GetMapping("/role")
public String getUserRole(Model model) {
model.addAttribute("role", "admin");
// Giá trị có thể là "admin", "user", hoặc "guest"
return "role";
}
}

Thymeleaf Template (role.html)


<div th:switch="${role}">
<p th:case="'admin'">🔴 Bạn là Admin - Có toàn quyền quản lý.</p>
<p th:case="'user'">Bạn là User - Có quyền truy cập cơ bản.</p>
<p th:case="'guest'">🔵 Bạn là Guest - Hạn chế quyền truy cập.</p>
<p th:case="*">⚠ Vai trò không xác định.</p>
</div>

27
Build select by Thymeleaf
◆ Thẻ <select> trong Thymeleaf giúp hiển thị danh sách tùy chọn (dropdown) với dữ
liệu động từ backend. Có thể sử dụng th:each để tạo các <option> tự động.
Controller (Java)
@Controller
public class CountryController {
@GetMapping("/form")
public String showForm(Model model) {
List<String> countries = List.of("Việt Nam", "Mỹ", "Nhật Bản", "Hàn Quốc");
model.addAttribute("countries", countries);
return "form";
}
}

<label>Chọn quốc gia:</label>


<select name="country">
<option th:each="country : ${countries}" th:value="${country}"
View (Thymeleaf - form.html) th:text="${country}"></option>
</select>
28
Custom Standard Dialect
◆ Thymeleaf is an extremely extensible template engine (in fact it could be
called a template engine framework) that allows you to define and
customize the way your templates will be processed to a fine level of
detail.
◆ An object that applies some logic to a markup artifact (a tag, some text, a
comment, or a mere placeholder if templates are not markup) is called
 a processor, and a set of these processors
 – plus perhaps some extra artifacts – is what a dialect is normally comprised of.

29
Step 1: Create a Custom Processor
◆ Let’s create a custom attribute my:text that works like th:text.
public class MyTextAttributeProcessor extends AbstractAttributeTagProcessor {
Custom Processor private static final String ATTR_NAME = "text";
(MyTextAttributeProcesso private static final int PRECEDENCE = 1000;
r.java) public MyTextAttributeProcessor(String dialectPrefix) {
super(TemplateMode.HTML, dialectPrefix,
null, false, ATTR_NAME,
true, PRECEDENCE, true
);
}
@Override
protected void doProcess(
ITemplateContext context, IProcessableElementTag tag,
AttributeName attributeName, String attributeValue,
IElementTagStructureHandler structureHandler) {
String processedText = (String) context.getVariable(attributeValue);
structureHandler.setBody(processedText, false);
}
}
30
Step 2: Create a Custom Dialect
Custom Dialect public class MyDialect extends AbstractDialect implements IProcessorDialect {
(MyDialect.java) private static final String DIALECT_NAME = "My Custom Dialect";
private static final String DIALECT_PREFIX = "my";
- Defines a custom dialect public MyDialect() {
named "My Custom Dialect". super(DIALECT_NAME);
- Uses the prefix my: (e.g., <p }
@Override
my:text="message"></p>). public String getPrefix() {
Registers MyTextAttributeProcessor return DIALECT_PREFIX;
}
@Override
public int getDialectProcessorPrecedence() {
return 1000;
}
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
return Collections.singleton(new MyTextAttributeProcessor(dialectPrefix));
}
}

31
Step 3: Register the Dialect in Thymeleaf Template Engine

Register Dialect in Spring Boot (ThymeleafConfig.java)


@Configuration
public class ThymeleafConfig {
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);

// Register custom dialect


templateEngine.addDialect(new MyDialect());

return templateEngine;
}
}

32
Step 4: Use the Custom Attribute in Thymeleaf Template

Thymeleaf Template (index.html)


<html xmlns:my="http://www.example.com/mydialect">
<head><title>Custom Dialect</title></head>
<body>
<p my:text="message"></p>
</body>
</html>

Equivalent to:

<p th:text="${message}"></p>

33
Advanced: Creating a Custom Element Processor
Besides custom attributes (my:text), you can create custom elements like:
<my:hello name="John"></my:hello>

Custom Element public class HelloElementProcessor extends AbstractElementTagProcessor {


private static final String TAG_NAME = "hello";
Processor private static final int PRECEDENCE = 1000;

(HelloElementProcessor.jav public HelloElementProcessor(String dialectPrefix) {


super(TemplateMode.HTML, dialectPrefix, TAG_NAME,
a) true, null, false, PRECEDENCE);
}
@Override
protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
IElementTagStructureHandler structureHandler) {
String name = tag.getAttributeValue("name");
structureHandler.setBody("Hello, " + name + "!", false);
}
}
This allows <my:hello name="John"></my:hello> to render as: Hello, John!
34
Custom Standard Dialect

35
Attribute Tag Processor

36
Summary
Concepts were introduced:
◆ Thymeleaf Template

◆ Building web applications using the Spring Framework.

 Spring Boot, Spring Data JPA, Spring MVC + Thymeleaf


◆ Amodern server-side Java template engine for both web and standalone

environments, capable of processing HTML, XML, JavaScript, CSS and even


plain text (Thymeleaf)

37
References
◆ https://www.baeldung.com/spring-template-engines
◆ https://www.thymeleaf.org/index.html

38

You might also like