14. Thymeleaf


14.1 官方文档

14.1.1 在线文档

14.1.2 离线文档

  • usingthymeleaf.pdf

14.2 基本介绍

● Thymeleaf 是什么

  1. Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,可完全替代 JSP
  2. Thymeleaf 是一个 java 类库,他是一个 xml/xhtml/html5 的模板引擎,可以作为 mvc 的 web 应用的 view 层

● Thymeleaf 的优点

  1. 实现 JSTL、 OGNL 表达式效果, 语法相似,java 程序员上手快
  2. Thymeleaf 模版页面无需服务器渲染,也可以被浏览器运行,页面简洁
  3. SpringBoot 支持 FreeMarker、Thymeleaf、veocity

● Thymeleaf 的缺点

  1. Thymeleaf:Thymeleaf is a modern server-side Java template engine for both web and standalone environments
  2. 缺点:并不是一个高性能的引擎,适用于单体应用
  3. 说明:如果要做一个高并发的应用,选择前后端分离更好,但是作为 SpringBoot 推荐的模板引擎,还是要学习 Thymeleaf 使用
  4. 后面还要学 Vue + ElementPlus + Axios + SpringBoot 前后端分离

14.3 Thymeleaf 机制说明

  1. Thymeleaf 是服务器渲染技术页面数据是在服务端进行渲染的

  2. 比如:manage.html 中一段 thymeleaf 代码,是在用户请求该页面时,有 thymeleaf 模板引擎完成处理的 (在服务端完成) ,并将结果页面返回

  3. 因此使用了 Thymeleaf ,并不是前后端分离

14.4 Thymeleaf 语法

14.4.1 表达式

  1. 表达式一览
表达式名字语法用途
变量取值${...}获取请求域、session 域、对象等值
选择变量*{...}获取上下文对象值
消息#{...}获取国际化等值
链接@{...}生成链接
片段表达式~{...}jsp:include 作用,引入公共页面片段
  1. 字面量
  • 文本值:‘xjs’ ,‘hello’ …
  • 数字:10,7,36.8
  • 布尔值:true,false
  • 空值:null
  • 变量:name,age,… 变量不能有空格
  1. 文本操作
  • 文本操作
  • 字符串拼接:+
  • 变量替换:age= ${age}

14.4.2 运算符

  1. 数学运算

    运算符:+ ,- ,* ,/ ,%

  2. 布尔运算

    运算符:and ,or
    一元运算: ! ,not

  3. 比较运算

    比较:> ,< ,>= ,<= ( gt ,lt ,ge ,le )
    等式:== ,!= ( eq ,ne )

  4. 条件运算

If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)

14.4.3 th 属性

html 有的属性,Thymeleaf 基本都有,而常用的属性大概有七八个,其中 th 属性执行的优先级从 1~8,数字越低优先级越高

  • th:text :设置当前元素的文本内容,相同功能的还有 th:utext,两者的区别在于前者不会转义 html 标签,后者会。优先级不高:order=7
  • th:value:设置当前元素的 value 值,类似修改指定属性的还有 th:srcth:href。优先级不高:order=6
  • th:each:遍历循环元素,和 th:textth:value 一起使用。注意该属性修饰的标签位置,详细往后看。优先级很高:order=2
  • th:if:条件判断,类似的还有 th:unlessth:switchth:case。优先级较高:order=3
  • th:insert:代码块引入,类似的还有 th:replaceth:include,三者的区别较大,若使用不恰当会破坏 html 结构,常用于公共代码块提取的场景。优先级最高:order=1
  • th:fragment:定义代码块,方便被 th:insert 引用。优先级最低:order=8
  • th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果。优先级一般:order=4
  • th:attr:修改任意属性,实际开发中用的较少,因为有丰富的其他 th 属性帮忙,类似的还有 th:attrappendth:attrprepend。优先级一般:order=5

14.4.4 迭代

在这里插入图片描述

 <tr th:each="prod : ${prods}">
   <td th:text="${prod.name}">Onions</td>
   <td th:text="${prod.price}">2.41</td>
   <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
 </tr>

14.4.5 条件运算

<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p>
</div>

14.4.6 使用 Thymeleaf -th 属性需要注意点

  1. 若要使用 Thymeleaf 语法,首先要声明名称空间:xmlns:th="http://www.thymeleaf.org"

  2. 明确各种标签的使用

    ● 设置文本内容 th:text
    ● 设置 input 的值 th:value
    ● 循环输出 th:each
    ● 条件判断 th:if
    ● 插入代码块 th:insert
    ● 定义代码块 th:fragment
    ● 声明变量 th:object

  3. th:each 的用法需要格外注意,打个比方:如果你要循环一个 div 中的 p 标签,则 th:each 属性必须放在 p 标签上。若你将 th:each 属性放在 div 上,则循环的是将整个 div

  4. 变量表达式中提供了很多的内置方法,该内置方法是用#开头,请不要与#{}消息表达式弄混

14.5 Thymeleaf 综合案例

14.5.1 需求说明

  • 说明:使用 SpringBoot + Thymeleaf 完成简单的用户登录-列表功能

在这里插入图片描述

在这里插入图片描述

14.5.2 思路分析

  • 说明:使用 SpringBoot + Thymeleaf 完成简单的用户登录
  • 思路分析/图解

在这里插入图片描述


14.5.3 代码实现

  1. 创建项目,项目名使用 springboot-usersys,使用灵活创建项目的方式
  2. 说明一下,要支持 Thymeleaf,需要加入 thymeleaf-starter,在 pom.xml 配置

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<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>com.xjs</groupId>
    <artifactId>springboot-usersys</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--导入springboot父工程-规定写法-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.5.3</version>
    </parent>

    <dependencies>
        <!--导入web项目场景启动器: 会自动导入和web开发相关的所有依赖[库/jar]-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--引入Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

        <!--引入 Thymeleaf-start
            1. 会进行默认配置
            2. 程序员按照规则开发即可
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

    </dependencies>

</project>
  1. 引入 starter-Thymeleaf ,项目会自动完成配置,程序员按照规则开发即可

在这里插入图片描述

  1. 创建 adminLogin.html 和 manage.html 和静态图片到指定目录,从准备好的拷贝即可,注意 将 html 文件放到 templates/ 目录下,该目录,不能直接访问

在这里插入图片描述

----- adminLogin.html -----

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>用户登陆</h1>
    <form action="#" method="post">
        <label style="color: red"></label><br/>
        用户名:<input type="text" style="width:150px" name="name"/><br/><br/>
        密 码 :<input type="password" style="width:150px" name="password"/><br/><br/>
        <input type="submit" value="登录"/>
        <input type="reset" value="重新填写"/>
    </form>
</div>
<hr/>
<!--<img src="images/logo.png"/>-->
</body>
</html>

----- manage.html -----

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>管理后台</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<a href='#'>返回管理界面</a> <a href='#'>安全退出</a> 欢迎您:XXX
<hr/>
<div style="text-align: center">
    <h1>管理雇员~</h1>
    <table border="1px" cellspacing="0" bordercolor="green" style="width:800px;margin:
auto">
        <tr bgcolor="pink">
            <td>id</td>
            <td>name</td>
            <td>pwd</td>
            <td>email</td>
            <td>age</td>
        </tr>
        <tr bgcolor="#ffc0cb" th:each="user:${users}">
            <td th:text="${user.id}">a</td>
            <td th:text="${user.name}">b</td>
            <td th:text="${user.password}">c</td>
            <td th:text="${user.age}">d</td>
            <td th:text="${user.email}">e</td>
        </tr>
    </table>
    <br/>
</div>
<hr/>
<!--<img src="images/logo.png"/>-->
</body>
</html>
  1. 创建 D:\xjs_springboot\springboot-usersys\src\main\java\com\xjs\springboot\bean\Admin.java
package com.xjs.springboot.bean;

import lombok.Data;

/**
 * @Author: 谢家升
 * @Version: 1.0
 */
@Data
public class Admin {
    private String name;
    private String password;
}

  1. 创建 D:\xjs_springboot\springboot-usersys\src\main\java\com\xjs\springboot\bean\User.java
package com.xjs.springboot.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author: 谢家升
 * @Version: 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String name;
    private String password;
    private Integer age;
    private String email;
}

  1. 创建 D:\xjs_springboot\springboot-usersys\src\main\java\com\xjs\springboot\controller\IndexController.java ,默认进入登录页面
package com.xjs.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import sun.awt.SunHints;

/**
 * @Author: 谢家升
 * @Version: 1.0
 */
@Controller
public class IndexController {

    //编写方法,转发到登录页面
    @GetMapping({"/", "/login"})
    public String login() {

        /**
         * 解读:
         * 1. 因为我们引入了 spring-boot-starter-thymeleaf
         * 2. 这里就会直接使用视图解析到 thymeleaf 下的模板文件 adminLogin.html
         */
        return "adminLogin";
    }

}

  1. 创建 D:\xjs_springboot\springboot-usersys\src\main\java\com\xjs\springboot\controller\AdminController.java ,处理登录请求 完成测试
package com.xjs.springboot.controller;

import com.xjs.springboot.bean.Admin;
import com.xjs.springboot.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;

/**
 * @Author: 谢家升
 * @Version: 1.0
 */
@Controller
public class AdminController {

    //响应用户的登录请求
    @PostMapping("/login")
    public String login(Admin admin, HttpSession session, Model model) {

        //验证用户是否合法
        if (StringUtils.hasText(admin.getName()) && "888".equals(admin.getPassword())) {

            /**合法 重定向到 manage.html
             * 1. 不使用请求转发是防止刷新页面会导致表单重复提交
             * 2. 这里为什么写的是 manage.html 因为这样可以更加明确的表示到哪个页面
             * 3. 这里的 manage.html 表示要去找 方法的映射路径为 manage.html
             */
            return "redirect:/manage.html";

        } else {
            //不合法 重新登录!
            return "adminLogin";
        }
    }

    //处理用户请求 manage.html
    @GetMapping("/manage.html")
    public String mainPage(Model model) {

        //这里集合-模拟用户数据,放入到request域中,并显示
        ArrayList<User> users = new ArrayList<>();
        users.add(new User(1, "关羽", "123456", 20, "gy@sohu.com"));
        users.add(new User(2, "张飞", "123456", 26, "zf@sohu.com"));
        users.add(new User(3, "赵云", "123456", 28, "zy@sohu.com"));
        users.add(new User(4, "马超", "123456", 22, "mc@sohu.com"));
        users.add(new User(5, "黄忠", "123456", 50, "hz@sohu.com"));

        //将数据放入到request域中
        model.addAttribute("users", users);

        return "manage"; //这里才是我们的视图解析到 /template/manage.html
    }

}

在这里插入图片描述

在这里插入图片描述

  1. 显示登录错误信息和提交 action

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 防止非法进入 manage.html

----- 修改 AdminController.java -----

package com.xjs.springboot.controller;

import com.xjs.springboot.bean.Admin;
import com.xjs.springboot.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;

/**
 * @Author: 谢家升
 * @Version: 1.0
 */
@Controller
public class AdminController {

    //响应用户的登录请求
    @PostMapping("/login")
    public String login(Admin admin, HttpSession session, Model model) {

        //验证用户是否合法
        if (StringUtils.hasText(admin.getName()) && "888".equals(admin.getPassword())) {

            //将登录用户保存到session
            session.setAttribute("loginAdmin", admin);

            /**合法 重定向到 manage.html
             * 1. 不使用请求转发是防止刷新页面会导致表单重复提交
             * 2. 这里为什么写的是 manage.html 因为这样可以更加明确的表示到哪个页面
             * 3. 这里的 manage.html 表示要去找 方法的映射路径为 manage.html
             */
            return "redirect:/manage.html";

        } else {
            //不合法 重新登录!
            model.addAttribute("msg", "账号/用户名错误");
            return "adminLogin";
        }
    }

    //处理用户请求 manage.html
    @GetMapping("/manage.html")
    public String mainPage(Model model, HttpSession session) {

        //这里暂时在方法中使用session验证,后面我们统一使用拦截器验证
        Object loginAdmin = session.getAttribute("loginAdmin");

        if (loginAdmin != null) { //说明成功登录过
            //这里集合-模拟用户数据,放入到request域中,并显示
            ArrayList<User> users = new ArrayList<>();
            users.add(new User(1, "关羽", "123456", 20, "gy@sohu.com"));
            users.add(new User(2, "张飞", "123456", 26, "zf@sohu.com"));
            users.add(new User(3, "赵云", "123456", 28, "zy@sohu.com"));
            users.add(new User(4, "马超", "123456", 22, "mc@sohu.com"));
            users.add(new User(5, "黄忠", "123456", 50, "hz@sohu.com"));

            //将数据放入到request域中
            model.addAttribute("users", users);

            return "manage"; //这里才是我们的视图解析到 /template/manage.html
        } else {
            //这里就返回登录页面,并给出提示
            model.addAttribute("msg", "你没有登录/请登录");

            return "adminLogin"; //请求转发到 adminLogin.html
        }
    }

}

----- adminLogin.html -----

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>用户登陆</h1>
    <form action="#" th:action="@{/login}" method="post">
        <label style="color: red" th:text="${msg}"></label><br/>
        用户名:<input type="text" style="width:150px" name="name"/><br/><br/>
        密 码 :<input type="password" style="width:150px" name="password"/><br/><br/>
        <input type="submit" value="登录"/>
        <input type="reset" value="重新填写"/>
    </form>
</div>
<hr/>
<!--<img src="images/logo.png"/>-->
</body>
</html>

在这里插入图片描述

  1. 显示登录的用户名,修改 manage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>管理后台</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<a href='#'>返回管理界面</a> <a href='#'>安全退出</a> 欢迎您:[[${session.loginAdmin.name}]]
<hr/>
<div style="text-align: center">
    <h1>管理雇员~</h1>
    <table border="1px" cellspacing="0" bordercolor="green" style="width:800px;margin:
auto">
        <tr bgcolor="pink">
            <td>id</td>
            <td>name</td>
            <td>pwd</td>
            <td>email</td>
            <td>age</td>
        </tr>
        <tr bgcolor="#ffc0cb" th:each="user:${users}">
            <td th:text="${user.id}">a</td>
            <td th:text="${user.name}">b</td>
            <td th:text="${user.password}">c</td>
            <td th:text="${user.age}">d</td>
            <td th:text="${user.email}">e</td>
        </tr>
    </table>
    <br/>
</div>
<hr/>
<!--<img src="images/logo.png"/>-->
</body>
</html>

在这里插入图片描述

  1. 完成安全退出功能,修改 manage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>管理后台</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<a href='#'>返回管理界面</a> <a href='#' th:href="@{/}">安全退出</a> 欢迎您:[[${session.loginAdmin.name}]]
<hr/>
<div style="text-align: center">
    <h1>管理雇员~</h1>
    <table border="1px" cellspacing="0" bordercolor="green" style="width:800px;margin:
auto">
        <tr bgcolor="pink">
            <td>id</td>
            <td>name</td>
            <td>pwd</td>
            <td>email</td>
            <td>age</td>
        </tr>
        <tr bgcolor="#ffc0cb" th:each="user:${users}">
            <td th:text="${user.id}">a</td>
            <td th:text="${user.name}">b</td>
            <td th:text="${user.password}">c</td>
            <td th:text="${user.age}">d</td>
            <td th:text="${user.email}">e</td>
        </tr>
    </table>
    <br/>
</div>
<hr/>
<!--<img src="images/logo.png"/>-->
</body>
</html>
2、对Spring Boot项目进行打包,可以在项目pom.xml文件中加入Maven打包插件 。 3、答案解析:IDEA开发工具对项目打包后,会在项目的 目录查看打成的包文件。 4、Spring Boot中自定义国际化文件区域信息解析器时,可以定制一个实现 接口的解析器类。 5、在Spring Boot中,使用路径扫描的方式整合内嵌式Servlet容器的Servlet、Filter、Listener三大组件时,需要在自定义组件上添加 、 和 注解进行声明。 6、Spring Boot区域信息解析器源码中是通过请求头中的 来确定具体需要使用哪种国际化语言文件的。 7、spring.thymeleaf.suffix指定了Thymeleaf模板页面的名称后缀,默认为 。 8、Spring Boot整合Redis时,需要添加 依赖启动器。 9、Spring Boot应用的启动类上标记有 注解。 10、使用@ConfigurationProperties注解注入属性值,可以添加Spring Boot提供的配置处理器依 赖 。 11、Windows下Redis安装包解压后包括一个服务启动指令: 。 12、构建Spring Boot项目选择Web依赖后,项目pom.xml中出现 和 两个核心依赖。 13、使用Spring Initializr方式构建Spring Boot项目默认以 方式打包。 14、Spring Boot整合Spring MVC实现Web开发,需要引入依赖启动器 。 15、Spring Boot中配置国际化文件,文件后缀名必须为 。 16、Spring Boot中可以通过使用 属性选择激活对应的多环境配置文件。 17、<form>表单中进行文件上传时,必须设置enctype= 。
06-02
感谢您的提问,以下是问题的答案: 2、正确。可以在项目的pom.xml文件中加入Maven打包插件,使用命令mvn package进行打包。 3、正确。IDEA开发工具对项目打包后,会在项目的target目录查看打成的包文件。 4、正确。可以定制一个实现LocaleResolver接口的解析器类来自定义国际化文件区域信息解析器。 5、正确。在自定义Servlet、Filter、Listener三大组件上需要添加@WebServlet、@WebFilter和@WebListener注解进行声明。 6、正确。Spring Boot区域信息解析器源码中是通过请求头中的Accept-Language来确定具体需要使用哪种国际化语言文件的。 7、正确。spring.thymeleaf.suffix指定了Thymeleaf模板页面的名称后缀,默认为.html。 8、正确。Spring Boot整合Redis时,需要添加spring-boot-starter-data-redis依赖启动器。 9、正确。Spring Boot应用的启动类上标记有@SpringBootApplication注解。 10、正确。使用@ConfigurationProperties注解注入属性值,可以添加spring-boot-configuration-processor依赖,用于生成配置元数据。 11、正确。Windows下Redis安装包解压后包括一个服务启动指令:redis-server.exe。 12、正确。构建Spring Boot项目选择Web依赖后,项目pom.xml中出现spring-boot-starter-web和spring-boot-starter-tomcat两个核心依赖。 13、正确。使用Spring Initializr方式构建Spring Boot项目默认以Jar方式打包。 14、正确。Spring Boot整合Spring MVC实现Web开发,需要引入spring-boot-starter-web依赖启动器。 15、正确。Spring Boot中配置国际化文件,文件后缀名必须为.properties或.yml。 16、正确。Spring Boot中可以通过使用spring.profiles.active属性选择激活对应的多环境配置文件。 17、正确。<form>表单中进行文件上传时,必须设置enctype="multipart/form-data"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

要学就学灰太狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值