Thymeleaf模版引擎

news2024/9/21 6:27:08

Thymeleaf是面向Web和独立环境的现代服务器端Java模版引擎,能够处理HTML、XML、JavaScript、CSS甚至纯文本。Thymeleaf旨在提供一个优雅的、高度可维护的创建模版的方式。为了实现这一目标,Thymeleaf建立在自然模版的概念上,将其逻辑注入到模版文件中,不会影响模版设计原型,从而改善了设计的沟通,弥合了设计和开发团队之间的差距。

Thymeleaf特点

  • Thymeleaf在有网络和无网络的环境下均可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持HTML原型,然后再HTML标签里增加额外的属性来达到模版+数据的展示方式。浏览器解释HTML是会忽略未定义的标签属性,所以Thymeleaf的模版可以静态地运行;当有数据返回到页面是,Thymeleaf会动态地替换掉静态内容,使页面动态显示
  • Thymeleaf开箱即用的特性。它支持标准方言和Spring方言,可以直接套用模版实现JSTL、OGNL表达式效果,避免每天套模板、改JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言
  • Thymeleaf提供Spring标准方言和一个与SpringMVC完美集成的可选模块,可以快速地实现表单绑定、属性编辑器、国际化等功能

添加依赖(启动器)

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

application.properties添加配置

springthymeleaf.cache=false

spring.thymeleaf.cache=false 是关闭Thymeleaf的缓存,不然在开发环境中修改页面不会立刻生效需要重启,生产可配置为true

Model准备(参考SpringBoot:Web开发(基于SpringBoot使用MyBatis-Plus+JSP开发)中使用MyBatisX快捷生成)

实体类

package com.ktjiaoyu.thymeleaf.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;

/**
 * 
 * @TableName sys_user
 */
@TableName(value ="sys_user")
@Data
public class User implements Serializable {
    /**
     * 编号
     */
    @TableId(type = IdType.AUTO)
    private Long usrId;

    /**
     * 姓名
     */
    private String usrName;

    /**
     * 密码
     */
    private String usrPassword;

    /**
     * 角色编号
     */
    private Long usrRoleId;
//    private String roleName;

    /**
     * 状态
     */
    private Integer usrFlag;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        User other = (User) that;
        return (this.getUsrId() == null ? other.getUsrId() == null : this.getUsrId().equals(other.getUsrId()))
            && (this.getUsrName() == null ? other.getUsrName() == null : this.getUsrName().equals(other.getUsrName()))
            && (this.getUsrPassword() == null ? other.getUsrPassword() == null : this.getUsrPassword().equals(other.getUsrPassword()))
            && (this.getUsrRoleId() == null ? other.getUsrRoleId() == null : this.getUsrRoleId().equals(other.getUsrRoleId()))
            && (this.getUsrFlag() == null ? other.getUsrFlag() == null : this.getUsrFlag().equals(other.getUsrFlag()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getUsrId() == null) ? 0 : getUsrId().hashCode());
        result = prime * result + ((getUsrName() == null) ? 0 : getUsrName().hashCode());
        result = prime * result + ((getUsrPassword() == null) ? 0 : getUsrPassword().hashCode());
        result = prime * result + ((getUsrRoleId() == null) ? 0 : getUsrRoleId().hashCode());
        result = prime * result + ((getUsrFlag() == null) ? 0 : getUsrFlag().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", usrId=").append(usrId);
        sb.append(", usrName=").append(usrName);
        sb.append(", usrPassword=").append(usrPassword);
        sb.append(", usrRoleId=").append(usrRoleId);
        sb.append(", usrFlag=").append(usrFlag);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

数据访问层

package com.ktjiaoyu.thymeleaf.mapper;

import com.ktjiaoyu.thymeleaf.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.PathVariable;


import java.util.List;

/**
* @author Administrator
* @description 针对表【sys_user】的数据库操作Mapper
* @createDate 2024-09-09 09:10:40
* @Entity com.ktjiaoyu.thymeleaf.entity.User
*/
public interface UserMapper extends BaseMapper<User> {


}




业务逻辑层

接口
package com.ktjiaoyu.thymeleaf.service;

import com.ktjiaoyu.thymeleaf.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;


import java.util.List;

/**
* @author Administrator
* @description 针对表【sys_user】的数据库操作Service
* @createDate 2024-09-09 09:10:40
*/
public interface UserService extends IService<User> {


}
实现类
package com.ktjiaoyu.thymeleaf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktjiaoyu.thymeleaf.entity.User;

import com.ktjiaoyu.thymeleaf.service.UserService;
import com.ktjiaoyu.thymeleaf.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* @author Administrator
* @description 针对表【sys_user】的数据库操作Service实现
* @createDate 2024-09-09 09:10:40
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    
}




控制器开发

package com.ktjiaoyu.thymeleaf.controller;

import com.ktjiaoyu.thymeleaf.entity.User;
import com.ktjiaoyu.thymeleaf.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Date;
import java.util.List;

/**
 * @author cuishujian
 * @date 2024/9/13
 */
//@Controller
public class ExampleController {

    @Resource
    private UserService userService;



    @GetMapping("/hello/{id}")
    public String getUser(@PathVariable("id") Long usrId, Model model){
        User user = userService.getUser(usrId);
        model.addAttribute("user",user);
        return "demo/hello";
    }

    
}

页面开发

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
  欢迎您,<span th:text="${user.usrName}">usrName</span>!
</body>
</html>

效果图

Thymeleaf的常用标签及其用法:

1. 数据绑定与文本替换

  • th:text:用于替换标签体内的文本内容。

    <span th:text="${user.name}">用户名</span>

  • th:utext:与th:text类似,但会处理HTML标签。

    <p th:utext="${htmlContent}">这里会展示HTML内容</p>

2. 条件判断

  • th:if:用于条件判断,如果条件为真,则显示标签体内容。

    <span th:if="${user.admin}">管理员</span>

  • th:unless:与th:if相反,条件为假时显示标签体内容。

    <a th:href="@{/login}" th:unless="${session.user != null}">Login</a>

3. 循环遍历

  • th:each:用于遍历集合、数组或Map等。
<ul> 
<li th:each="user : ${userList}" th:text="${user.name}"></li> 
</ul>

4. URL与链接

  • th:href:用于构建URL。

    <a th:href="@{/user/{id}(id=${user.id})}">查看用户</a>

  • th:action:用于表单的提交地址。

    <form th:action="@{/submit}"> 
    ... 
    </form>

5. 样式与属性

  • th:style:用于设置标签的style属性。

    <div th:style="'background-color: ' + ${bgColor} + ';'">...</div>

  • th:attr:用于设置标签的任意属性。

    <img th:attr="src=@{/images/logo.png},alt=${altText}" />

6. 布局与片段

  • th:fragment:定义一个可以复用的片段(Fragment)。

    <div th:fragment="header">页眉内容</div>

  • th:include 和 th:replace:用于引入其他模板文件中的片段。

    <!-- 引入片段,但保留自己的标签 --> 
    <div th:include="header :: header"></div> 
    
    
    <!-- 替换整个标签为引入的片段 --> 
    <div th:replace="footer :: footer"></div>

7. 表达式与内置对象

Thymeleaf支持多种表达式,包括选择变量表达式${...}、选择表达式*{...}、消息表达式#{...}等。此外,它还提供了许多内置对象,如#strings#numbers#dates等,用于执行字符串、数字、日期等的操作。

8. 其他常用标签

  • th:id:用于替换HTML元素的id属性。
  • th:value:用于设置表单元素的value属性。
  • th:selected:用于设置下拉框(<select>)中选中的项。
  • th:checked:用于设置复选框(<input type="checkbox">)或单选按钮(<input type="radio">)的选中状态。
  • th:switch 和 th:case:用于多路选择,类似于Java中的switch语句。

Thymeleaf的标签库非常丰富,上述只是其中的一部分常用标签。在实际开发中,可以根据项目需求选择合适的标签来简化页面开发。

表达式

1. 变量表达式

  • 语法${...}
  • 用途:用于在模板中输出变量的值。
  • 示例<h1 th:text="${pageTitle}">Page Title</h1>

2. 选择变量表达式

  • 语法*{...}
  • 用途:用于从选定对象中选择属性或调用方法,类似于JSP中的EL表达式。
  • 示例<p th:text="*{user.name}">Default Name</p>

3. 消息表达式

  • 语法#{...}
  • 用途:用于获取国际化内容,根据当前环境选择合适的文本。
  • 示例<span th:text="#{welcome.message}">Welcome!</span>

4. 链接URL表达式

  • 语法@{...}
  • 用途:用于生成链接或动态URL,支持相对路径和绝对路径。
  • 示例
    • 绝对URL:<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>
    • 相对URL:<a th:href="@{/product/{id}(id=1)}">Product Details</a>

5. 字面量

  • 文本'one text', 'another one!'
  • 数值0, 34, 3.0, 12.3
  • 布尔类型true, false
  • 空值null

6. 文本操作

  • 字符串连接:使用+操作符。
  • 示例<span th:text="'Welcome to our application, ' + ${user.name} + '!'">

7. 算术运算

  • 支持的运算符:+, -, *, /, %
  • 示例:<p th:text="${number1} + ${number2}"></p>

8. 布尔操作

  • 支持的运算符:and, or
  • 非操作符:!, not

9. 关系操作符

  • 比较运算符:>, <, >=, <=(HTML中转义为gt, lt, ge, le
  • 相等运算符:==, !=(或eq, ne

10. 条件表达式

  • If-then(if) ?(then)
  • If-then-else(if) ?(then) : (else)
  • 示例:<tr th:class="${row.even}?'even':'odd'"></tr>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2151540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VUE3配置路由(超级详细)

第一步创建vue3的项目

(八)使用Postman工具调用WebAPI

访问WebAPI的方法&#xff0c;Postman工具比SoapUI好用一些。 1.不带参数的get请求 [HttpGet(Name "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() {return Enumerable.Range(1, 5).Select(index > new WeatherForecast{Date DateT…

【TabBar嵌套Navigation案例-JSON的简单使用 Objective-C语言】

一、JSON的简单使用 1.我们先来看一下示例程序里边,产品推荐页面, 在我们这个产品推荐页面里面, 它是一个CollectionViewController,注册的是一个xib的一个类型,xib显示这个cell,叫做item,然后,这个邮箱大师啊,包括这个图标,以及这些东西,都是从哪儿来的呢,都是从…

NLP 主要语言模型分类

文章目录 ngram自回归语言模型TransformerGPTBERT&#xff08;2018年提出&#xff09;基于 Transformer 架构的预训练模型特点应用基于 transformer&#xff08;2017年提出&#xff0c;attention is all you need&#xff09;堆叠层数与原transformer 的差异bert transformer 层…

SpringBoot 项目如何使用 pageHelper 做分页处理 (含两种依赖方式)

分页是常见大型项目都需要的一个功能&#xff0c;PageHelper是一个非常流行的MyBatis分页插件&#xff0c;它支持多数据库分页&#xff0c;无需修改SQL语句即可实现分页功能。 本文在最后展示了两种依赖验证的结果。 文章目录 一、第一种依赖方式二、第二种依赖方式三、创建数…

低空经济刚需篇:各种道路不畅地区无人机吊装详解

低空经济作为近年来备受关注的新兴经济形态&#xff0c;其核心在于利用3000米以下的低空空域进行各种飞行活动&#xff0c;以无人机、电动垂直起降飞行器(eVTOL)等为载体&#xff0c;推动交通、物流、巡检、农林植保、应急救援等多领域的变革。在道路不畅的地区&#xff0c;无人…

信息安全数学基础(20)中国剩余定理

前言 信息安全数学基础中的中国剩余定理&#xff08;Chinese Remainder Theorem&#xff0c;简称CRT&#xff09;&#xff0c;又称孙子定理&#xff0c;是数论中一个重要的定理&#xff0c;主要用于求解一次同余式组。 一、背景与起源 中国剩余定理最早见于我国南北朝时期的数学…

存储 NFS

目录 1.存储的应用场景 2.存储分类 3.NFS服务组成 4.环境说明 ​编辑 5.服务端部署 6.NFS服务端的配置 7.NFS服务端本地进行测试 1.存储的应用场景 存储一般用于上传网站数据&#xff08;内容&#xff09;&#xff0c;一般用于在网站集群中。使用存储的话用户上传的…

推荐系统-电商直播 多目标排序算法探秘

前言&#xff1a; 电商直播已经成为电商平台流量的主要入口&#xff0c;今天我们一起探讨推荐算法在直播中所面临的核心问题和解决方案。以下内容参考阿里1688的技术方案整理完成。 一、核心问题介绍 在电商网站中&#xff0c;用户的主要行为是在商品上的行为&#xff0c;直播…

Java8四大函数接口

一、说明 1.函数式接口的使用说明说明&#xff1a; 函数式接口是Java8的一个新特性。如果一个接口中&#xff0c;只声明了一个抽象方法&#xff0c;则此接口就称为函数式接口。我们可以在一个接口上使用 FunctionalInterface 注解&#xff0c;这样做可以检查它是否是一个函数…

【数据结构】排序算法---基数排序

文章目录 1. 定义2. 算法步骤2.1 MSD基数排序2.2 LSD基数排序 3. LSD 基数排序动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 ⚠本节要介绍的不是计数排序 1. 定义 基数排序&#xff08;英语&#xff1a;Radix sort&#xff09;是一种非比较型的排序算法&…

基于ExtendSim的 电子制造 仿真模型

说明&#xff1a; 此模型表示电路板制造设施。该过程有4个步骤&#xff1a; *焊料制备 *组件放置 *烤箱 *检查 详情&#xff1a; *烤箱的容量为10张卡&#xff0c;但如果烤箱循环开始时仅能处理5张卡&#xff0c;则最多只能处理5张。 *如果检查员发现问题&#xff0c;他们将修理…

C++——map和set的使用以及map系列

目录 map和set的使用 1. 序列式容器和关联式容器 2. set系列的使⽤ 2.1 set和multiset参考⽂档 2.2 set类的介绍 2.3 set的构造和迭代器 2.4 set的增删查 set的增删查关注以下⼏个接⼝即可&#xff1a; 2.6 find和erase使⽤样例&#xff1a; lower_bound(); upper_bo…

Css_动态渐变圆圈旋转效果

1、效果图 2、实现代码 <template><div class"box"><div class"line"></div><div class"lineNew"></div></div> </template><script lang"ts" setup></script><styl…

MySQL篇(存储引擎 - InnoDB存储引擎架构)(持续更新迭代)

目录 一、逻辑存储结构 1. 表空间 2. 段 3. 区 4. 页 5. 行 二、架构 1. 简介 2. 内存结构&#xff08;四部分&#xff09; Buffer Pool Change Buffer Adaptive Hash Index Log Buffer 3. 磁盘结构&#xff08;七部分&#xff09; System Tablespace File-Per-…

pdf文件怎么直接翻译?使用这些工具让翻译变得简单

在全球化日益加深的职场环境中&#xff0c;处理外语PDF文件成为了许多职场人士面临的共同挑战。 面对这些“加密”的信息宝库&#xff0c;如何高效、准确地将英文pdf翻译成对应语言&#xff0c;成为了提升工作效率的关键。 以下是几款在PDF翻译领域表现出色的软件&#xff0c…

化繁为简:中介者模式如何管理复杂对象交互

化繁为简&#xff1a;中介者模式如何管理复杂对象交互 中介者模式 是一种行为型设计模式&#xff0c;定义了一个中介者对象&#xff0c;来封装一组对象之间的交互。中介者模式通过将对象之间的交互行为从多个对象中抽离出来&#xff0c;集中封装在一个中介者对象中&#xff0c;…

智能除螨仪——NV040D-SOP8语音芯片方案引领除螨仪新时代

随着物联网技术的快速发展&#xff0c;除螨仪作为家庭清洁的重要工具&#xff0c;其智能化、人性化的设计成为提升市场竞争力的关键。置入语音芯片的除螨仪&#xff0c;通过开机提示、工作状态反馈、操作指引、故障提醒等内容。用户可以更加直观地了解除螨仪的工作状态&#xf…

开发谷歌插件之GA埋点

目录 一、背景 二、踩坑 三、谷歌插件开发的GA埋点的实现方式 一、背景 开发了一个谷歌插件&#xff0c;领导需要对用户的一些行为进行分析&#xff0c;于是让我在代码里面加上GA埋点。由于我们的PC端的项目一直都有进行GA埋点&#xff0c;当时就想着&#xff0c;这不就是把…

Spring Cloud Alibaba-(4)Sentinel【流控和降级】

Spring Cloud Alibaba-&#xff08;1&#xff09;搭建项目环境 Spring Cloud Alibaba-&#xff08;2&#xff09;Nacos【服务注册与发现、配置管理】 Spring Cloud Alibaba-&#xff08;3&#xff09;OpenFeign【服务调用】 Spring Cloud Alibaba-&#xff08;4&#xff09;Sen…