SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)

文章目录

  • 前言
  • 一 Thymeleaf 介绍
    • 1.1 概念
    • 1.2 特点
  • 二 Thymeleaf详解
    • 1 表达式
      • 1.1 变量表达式
      • 1.2 选择表达式
      • 1.3 URL表达式
        • 1.3.1 url表达式
        • 1.3.2 文本替换
        • 1.3.2 字符串拼接
      • 1.4 表达式常见用法
      • 1.5 常用th标签
      • 1.6 基本用法
        • 1.6.1 赋值、字符串拼接
        • 1.6.2 条件判断if/unless
        • 1.6.3 for循环
        • 1.6.4 status状态变量
        • 1.6.5 内联文本
        • 1.6.6 内联文本
        • 1.6.7 内嵌对象
        • 1.6.8 布局
  • 三 Thymeleaf入门案例
    • 1启动器
    • 2 pom.xml
    • 3 配置文件
    • 4 相关的静态文件
    • 5 后台UserController
    • 6 实体类User
    • 7 UserMapper
    • 8 UserService
    • 9 UserServiceImpl
  • 四 测试结果
    • 1 循环
    • 2 布局、内置对象和其他指令


前言

本篇记录我在学习SpringBoot的过程中,对Thymeleaf的学习经验;
Thymeleaf是一种

提示:以下是本篇文章正文内容,下面案例可供参考

一 Thymeleaf 介绍

1.1 概念

Thymeleaf 是一个跟 FreeMarker 类似的模板引擎,它可以完全替代 JSP 。;

1.2 特点

  • 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,无网络显示静态内容,有网络用后台得到数据替换静态内容;

  • 与SpringBoot完美整合,springboot默认整合thymelea

二 Thymeleaf详解

1 表达式

Thymeleaf中的表达式分为三种

1.1 变量表达式

就是OGNL表达式或者Spring EL表达式(spring中在jsp页面中获取session或其他内置对象的数据)如:${session.user.name};
它们将以HTML标签的一个属性来表示:

<h5>表达式h5>
<span>${text}span>
<span th:text="${text}">你好 thymleafspan>

1.2 选择表达式

也可以叫星号表达式,有点像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如: *{customer.name};被指定的对象object由th:object属性定义,
代码如下:

 
        <tr th:each="user, status : ${users}" th:object="${user}" th:bgcolor="${status.even}? 'gray'">
            <td th:text="${status.even}">truetd>
            <td th:text="${status.odd}">truetd>
            <td th:text="${status.index}">0td>
            <td th:text="${status.count}">1td>
            <td th:text="${user.id}">1td>
            <td th:text="*{name}">zhangsantd>
            <td th:text="*{userName}">张三td>
            <td th:text="${user.age}">20td>
            <td th:text="${user.sex} == 1 ? '' : ''">td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30td>

            <td th:text="${user.note}">1td>
            <td>
                
                <a th:href="@{delete(id=${user.id}, userName= *{userName})}">删除a>
                
                <a th:href="|/update/${user.id}|">修改a>
                
                <a th:href="'approve/' + ${user.id}">审核a>
            td>
        tr>

1.3 URL表达式

  • URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写
  • URL还可以设置参数: @{/order/details(id=${orderId}, name=*{name})

1.3.1 url表达式

<a th:href="@{/delete(id=${user.id}, userName=*{userName})}">删除a>

1.3.2 文本替换

<a th:href="|/update/${user.id}|">修改

1.3.2 字符串拼接

<a th:href="'/approve/' + ${user.id}">审核a>

1.4 表达式常见用法

字面(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,…
  • 文本操作(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
  • 比较和等价(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)

1.5 常用th标签

关键字 功能介绍 案例
th:text 文本替换 < p th:text="${collect.description}">description< /p >
th:id 替换id < input th:id="‘xxx’ + ${collect.id}"/ >
th:utext 支持html的文本替换 < p th:utext="${htmlcontent}">conten< /p >
th:object 替换对象 < div th:object="${session.user}">
th:value 属性赋值 < input th:value="${user.name}" />
th:with 变量赋值运算 < div th:with=“isEven=${prodStat.count}%2==0”>< /div>
th:style 设置样式 th:style="‘display:’ + @{(${sitrue} ? ‘none’ : ‘inline-block’)} + ‘’"
th:onclick 点击事件 th:οnclick="‘getCollect()’"
th:each 属性赋值 tr th:each=“user,userStat:${users}”>
th:if 判断条件 < a th:if="${userId == collect.userId}" >
th:unless 和th:if判断相反 < a th:unless="${userId == collect.userId}" >
th:href 链接地址
th:case th:switch的一个分支 < p th:case="‘admin’">User is an administrator< /p>
th:fragment 布局标签,定义一个代码片段,方便其它地方引用 < div th:fragment=“alert”>
th:include 布局标签,替换内容到引入的文件 < head th:include=“layout :: htmlhead” th:with=“title=‘xx’”>< /head>
th:replace 布局标签,替换整个标签到引入的文件 < div th:replace=“fragments/header :: title”>< /div>
th:selected selected选择框 选中 th:selected="( {configObj.dd})"
th:src 图片类地址引入< img class=“img-responsive” alt=“App Logo” th:src="@{/img/logo.png}" />
th:inline 定义js脚本可以使用变量 < script type=“text/javascript” th:inline=“javascript”>
th:action 表单提交的地址 < form action=“subscribe.html” th:action="@{/subscribe}">
th:remove 删除某个属性 < tr th:remove=“all”> 1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。
th:attr 设置标签属性,多个属性可以用逗号分隔 th:attr=“src=@{/image/aa.jpg},title=#{logo}”,此标签不太优雅,一般用的比较少。

1.6 基本用法

1.6.1 赋值、字符串拼接

<a th:href="|/update/${user.id}|">修改a>
<a th:href="'/approve/' + ${user.id}">审核a>

1.6.2 条件判断if/unless

if是条件成立是生效,unless是条件不成立是生效,两者恰好相反

<h5>if指令h5>
<a th:if="${users.size() > 0}">查询结果存在a><br>
<a th:if="${users.size() <= 0}">查询结果不存在a><br>
<a th:unless="${session.user != null}" href="#">登录a><br>

1.6.3 for循环


        <tr th:each="user, status : ${users}" th:object="${user}" th:bgcolor="${status.even}? 'gray'">
            <td th:text="${status.even}">truetd>
            <td th:text="${status.odd}">truetd>
            <td th:text="${status.index}">0td>
            <td th:text="${status.count}">1td>
            <td th:text="${user.id}">1td>
            <td th:text="*{name}">zhangsantd>
            <td th:text="*{userName}">张三td>
            <td th:text="${user.age}">20td>
            <td th:text="${user.sex} == 1 ? '' : ''">td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30td>

            <td th:text="${user.note}">1td>
            <td>
                
                <a th:href="@{delete(id=${user.id}, userName= *{userName})}">删除a>
                
                <a th:href="|/update/${user.id}|">修改a>
                
                <a th:href="'approve/' + ${user.id}">审核a>
            td>
        tr>

1.6.4 status状态变量

  • index:当前迭代对象的index(从0开始计算)
  • count: 当前迭代对象的index(从1开始计算)
  • size:被迭代对象的大小
  • current:当前迭代变量
  • even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
  • first:布尔值,当前循环是否是第一个
  • last:布尔值,当前循环是否是最后一个

1.6.5 内联文本

以**[[…]]**方式表示,使用时必须使用“th:inline=”text”激活,th:inline可以在
父级标签内使用,甚至作为body的标签。内联文本尽管比th:text的代码少,不利于原型显示。使用的内容必须是后端返回的model总有的内容;

  • 在thymeleaf指令中显示
<h6 th:text="${text}">静态内容h6>
  • 使用内联文本显示model attribute
<h5>内联文本h5>
<div>
   <h6 th:inline="text">[[${text}]]h6>
   <h6 th:inline="none">[[${text}]]h6>
   <h6>[[${text}]]h6>
div>

**PS:**能用th指令就用替换指令

1.6.6 内联文本

与内联文本相似,以th:inline=”text/javascript/none”激活,内容是js脚本。拥有js脚本的能力;

<h5>内联jsh5>
<script th:inline="javascript">
var text = '[[${text}]]';
console.log(text);
script>

1.6.7 内嵌对象

Thymeleaf提供了了一系列Utility对象(内置于Context中),可以通过**# + 对象名**的方式直接调用其中的方法。

对象 功能
dates java.util.Date**的功能方法类。
calendars 类似#dates,面向java.util.Calendar
numbsers 格式化数字的功能方法类
strings 字符串对象的功能类
objects 对objects的功能类操作。
bools 对布尔值求值的功能方法。
arrays 对数组的功能类方法。
lists/sets/maps/ 对list/set/map功能类方法

1.6.8 布局

通过footer标签定义页面;

DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<body>
		<footer th:fragment="copy(title)">
			© 2020 开课吧版权所有<br>
			<span th:text="${title}">title footerspan>
		footer>
	body>
html>

然后,在页面任何地方引入:

<h5>thymeleaf布局h5>
<div th:insert="footer :: copy('开课吧1')">div>
<div th:replace="footer :: copy('开课吧2')">div>
<div th:include="footer :: copy('开课吧3')">div>
  • th:insert :保留自己的主标签,保留th:fragment的主标签。
  • th:replace :不要自己的主标签,保留th:fragment的主标签。
  • th:include :保留自己的主标签,不要th:fragment的主标签。

三 Thymeleaf入门案例

1启动器

Thymelea启动器在依赖坐标

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

2 pom.xml


<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.0modelVersion>

    <groupId>com.kaikebagroupId>
    <artifactId>sb-thymeleaf-01artifactId>
    <version>1.0-SNAPSHOTversion>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.11.RELEASEversion>
    parent>

    <dependencies>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>

        
        <dependency>
            <groupId>tk.mybatisgroupId>
            <artifactId>mapper-spring-boot-starterartifactId>
            <version>2.1.5version>
        dependency>

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.25version>
        dependency>
    dependencies>

project>

3 配置文件

application.properties

	server.port=8080
	logging.level.com.kaikeba=debug
	
	# 数据库信息
	spring.datasource.url=jdbc:mysql://localhost:3306/springboot-jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
	spring.datasource.password=root
	spring.datasource.username=root
	spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
	
	# 关闭thymeleaf缓存
	spring.thymeleaf.cache=false

4 相关的静态文件

由于springboot为thymeleaf自动添加的视图解析器会加上templates前缀,所以我们的所有静态文件都必须在**/resources/templates/** 下,
SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)_第1张图片
定义的布局footer.html:

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
    <footer th:fragment="copy(title)">
        ©2020开课吧版权所有<br/>
        <span th:text="${title}">title footerspan>
    footer>
body>
html>

测试的temp.html:

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>

<h2>Thymeleaf布局h2>

<div th:insert="footer :: copy('开课吧1')">div>

<div th:replace="footer :: copy('开课吧22')">div>

<div th:include="footer :: copy('开课吧333')">div>

<h2>内置变量h2>
<span th:text="${#dates.format(#dates.createNow(), 'yyyy-MM-dd HH:mm:ss')}">获取当前日期span><br/>
<span th:text="${#strings.substring(text, 4, 6)}">截取字符串span><br/>
<span th:text="${#strings.length(text)}">span><br/>
<span th:text="${#strings.randomAlphanumeric(6)}">随机字符串span><br/>
<span th:text="${#strings.equals(text, 'hello')}">equals等值判断span><br/>

<h2>if指令h2>
<a th:if="${users.size() > 0}"> 查询结果存在a><br/>
<a th:if="${users.size() <= 0}">查询结果不存在a><br/>
<a th:unless="${session.user != null}">登录a><br/>

<h2>内联文本h2>
<span th:text="${text}">静态内容span>
<div>
    <h3 th:inline="text">${text}h3>
    <h3>[[${text}]]h3>
div>

<h3>内联JSh3>
<span>内容在console.logspan>
<script th:inline="javascript">
    var text = '[[${text}]]';
    console.log(text);
script>


body>
html>

测试循环的user.html:

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
    <title>Thymeleaf 入门案例title>
    <meta charset="UTF-8">
    <style type="text/css">
        table {
            border-collapse: collapse;
            font-size: 15px;
            width: 80%;
            margin: auto;
        }

        table, th, td {
            border: 1px solid darkslategray;
            padding: 10px
        }
    style>
head>
<body>
<div style="text-align: center">
    <span style="color: darkslategray; font-size: 30px">欢迎光临span>
    <hr/>
    <table class="list">
        <tr>
            <th>偶数行th>
            <th>奇数行th>
            <th>序号indexth>
            <th>序号countth>
            <th>IDth>
            <th>姓名th>
            <th>用户名th>
            <th>年龄th>
            <th>性别th>
            <th>生日th>
            <th>备注th>
            <th>操作th>
        tr>
        
        <tr th:each="user, status : ${users}" th:object="${user}" th:bgcolor="${status.even}? 'gray'">
            <td th:text="${status.even}">truetd>
            <td th:text="${status.odd}">truetd>
            <td th:text="${status.index}">0td>
            <td th:text="${status.count}">1td>
            <td th:text="${user.id}">1td>
            <td th:text="*{name}">zhangsantd>
            <td th:text="*{userName}">张三td>
            <td th:text="${user.age}">20td>
            <td th:text="${user.sex} == 1 ? '' : ''">td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30td>

            <td th:text="${user.note}">1td>
            <td>
                
                <a th:href="@{delete(id=${user.id}, userName= *{userName})}">删除a>
                
                <a th:href="|/update/${user.id}|">修改a>
                
                <a th:href="'approve/' + ${user.id}">审核a>
            td>
        tr>
    table>
div>

body>
html>

5 后台UserController

package com.kaikeba.controller;

import com.kaikeba.entity.pojo.User;
import com.kaikeba.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author sunyang
 * @date 2021/5/31 11:32
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/all")
    public String searchAll(Model model) {
        List<User> all = userService.findAll();
        model.addAttribute("users", all);
        model.addAttribute("text","我这是测试th:text");
        return "user";
    }

    /**
     * @desc thymeleaf测试
     *
     * @param model
     * @return java.lang.String
     * @date 2021/5/31 16:42
     * @auther sunyang
     */
    @GetMapping("/temp")
    public String temp(Model model) {
        List<User> all = userService.findAll();
        model.addAttribute("users", all);
        model.addAttribute("text","我这是测试th:text");
        return "temp";
    }
}

6 实体类User

package com.kaikeba.entity.pojo;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

/**
 * @author sunyang
 * @date 2021/5/31 11:30
 */
@Table(name = "tbs_user")
public class User {
    // 主键 自增
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private Integer sex;
    private Date birthday;
    private Date created;
    private Date updated;
    private String note;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setUpdated(Date updated) {
        this.updated = updated;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", birthday=" + birthday +
                ", created=" + created +
                ", updated=" + updated +
                ", note='" + note + '\'' +
                '}';
    }
}

7 UserMapper

package com.kaikeba.mapper;

import com.kaikeba.entity.pojo.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author sunyang
 * @date 2021/5/31 11:29
 */
@Mapper
public interface UserMapper extends tk.mybatis.mapper.common.Mapper<User> {
}

8 UserService

package com.kaikeba.service;

import com.kaikeba.entity.pojo.User;

import java.util.List;

/**
 * @author sunyang
 * @date 2021/5/31 11:29
 */
public interface UserService {
    /**
     * @return java.util.List
     * @desc 查询所有数据
     * @date 2021/5/31 11:31
     * @auther sunyang
     */
    List<User> findAll();
}

9 UserServiceImpl

package com.kaikeba.service.impl;

import com.kaikeba.entity.pojo.User;
import com.kaikeba.mapper.UserMapper;
import com.kaikeba.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author sunyang
 * @date 2021/5/31 11:30
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.selectAll();
    }
}

四 测试结果

1 循环

SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)_第2张图片

2 布局、内置对象和其他指令

SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)_第3张图片
内联的js:
SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)_第4张图片

你可能感兴趣的:(java,html)