Skip to content
鼓励作者:欢迎打赏犒劳

01-Thymeleaf

依赖

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

首次访问页面

非常的简单,springBoot天生和thymeleaf整合的很紧密,只需要在src/main/resources/templates/目录下创建index.html ,然后创建controller就好了,什么都不需要配置

java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String index() {
        return "index"; // 返回模板名,无需.html后缀
    }
}

代码抽离

比如我们想把头部信息给抽离出来,以便其他页面使用。

其实很简单,记住,

th:fragment 是定义一个代码片段,nav是代码片段的名字,也可以说成方法 (activePage) 是参数

1、首先,在src/main/resources/templates/component/目录下创建一个新的HTML文件,例如head.html。这个文件将包含你的导航栏代码。

如果你想让某些页面的导航栏略有不同(例如,当前页面对应的导航项有“active”类),可以通过传递参数给片段或者通过CSS/JavaScript动态处理。

例如,head.html以接受一个activePage参数,并根据这个参数添加active类:

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
    <div th:fragment="nav(activePage)">
        <ul>
            <li th:class="${activePage == 'home' ? 'active' : ''}">
                <a href="/" th:href="@{/}">首页</a>
            </li>
            <li th:class="${activePage == 'about' ? 'active' : ''}">
                <a href="/about" th:href="@{/about}">关于我们</a>
            </li>
        </ul>
    </div>
</body>
</html>

2、在其他页面中引入导航栏片段

接下来,在你想要显示导航栏的任何页面中使用Thymeleaf的th:insertth:replace属性来包含这个导航栏片段。例如,在index.html中:

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>首页</title>
</head>
<body>
<!-- 插入导航栏 -->
<div th:insert="~{component/head :: nav('home') }"></div>

<h1>欢迎来到首页</h1>
<!-- 页面主体内容 -->
</body>
</html>

渲染数据

渲染集合

java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;
import java.util.List;

@Controller
public class ListController {

    @GetMapping("/items")
    public String showItems(Model model) {
        List<CategoryDO> list = categoryService.list();
        model.addAttribute("items", items);
        return "items"; // 返回模板名,无需.html后缀
    }
}

渲染

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<table class="layui-table">
    <thead>
    <tr>
        <th>类目名称</th>
        <th>创建时间</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="item : ${items}">
        <td th:text="${item.name}"></td>
        <td th:text="${item.createTime}"></td>
        <td> <button  th:onclick="|edit(${item.id})|">编辑</button></td>
    </tr>
    </tbody>
</table>
</html>

动态加载JS文件

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>My Page</title>
    <!-- 动态加载JS文件 -->
    <script th:src="@{/static/js/utils/url.js(v=${version})}"></script>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>

动态渲染class样式

html
<!--假设你有一个布尔值active在你的模型中,用于决定是否应用一个名为active的CSS类:-->
<div th:class="${active} ? 'active' : 'inactive'">内容</div>
<div th:class="${code == 'sku'} ? 'active' : 'inactive'">内容</div>

<!--如果你想在已有的class基础上追加额外的类(而不是完全替换它们),可以使用th:classappend-->
<div class="default-class" th:classappend="${active} ? 'active' : ''">内容</div>

if-else渲染

通过组合 th:ifth:unless 实现互斥条件:

html
<!-- 用户已登录 -->
<div th:if="${user != null}">
    欢迎,<span th:text="${user.name}"></span>!
</div>

<!-- 用户未登录 -->
<div th:unless="${user != null}">
    <a href="/login">请登录</a>
</div>

使用 th:switch 实现多条件分支

html
<div th:switch="${user.role}">
  <span th:case="'admin'" class="admin-menu">管理员菜单</span>
  <span th:case="'user'" class="user-menu">用户菜单</span>
  <span th:case="*" class="guest-menu">访客菜单</span>
</div>

三元表达式

html
<!-- 如果 message 不为空则显示 message,否则显示默认文本 -->
<span th:text="${show} ? '你好'  : '暂无消息'"></span>

th:if 中直接使用逻辑运算符(and/or/not):

html
<div th:if="${user.active and user.role == 'admin'}">
  用户是活跃管理员时显示
</div>

<div th:if="${not #strings.isEmpty(user.comment)}">
  用户评论不为空时显示
</div>

绑定onclick

html
<button  th:onclick="|edit(${item.id})|">编辑</button>

生成模版文件

java
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

@Controller
public class ExampleController {

    private final TemplateEngine templateEngine;

    public ExampleController(TemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }

    @GetMapping("/generateFile")
    public ResponseEntity<ByteArrayResource> generateFile() throws IOException {
        Context context = new Context();
        context.setVariable("title", "Thymeleaf Example");
        context.setVariable("message", "This is a message from the controller.");

        String htmlContent = templateEngine.process("example", context);
        
        // 将 HTML 内容转为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(htmlContent.getBytes());
        ByteArrayResource resource = new ByteArrayResource(outputStream.toByteArray());

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=example.html")
                .contentType(MediaType.TEXT_HTML)
                .body(resource);
    }
}

src/main/resources/templates 目录下创建一个 Thymeleaf 模板文件,例如 example.html

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>My Example</title>
</head>
<body>
    <h1 th:text="${title}">Default Title</h1>
    <p th:text="${message}">Default message</p >
</body>
</html>

如有转载或 CV 的请标注本站原文地址