其他分享
首页 > 其他分享> > Spring Boot基础Ch05

Spring Boot基础Ch05

作者:互联网

Spring Boot基础Ch05

Spring Boot Ch05(Thymeleaf 模板引擎)

Thymeleaf模板引擎介绍

模板引擎

  1. 模板引擎是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文 档,用于网站的模板引擎就会生成一个标准的 HTML 文档。

  2. 模板引擎的实现方式有很多,最简单的是“置换型”模板引擎,这类模板引擎只是将指定 模板内容(字符串)中的特定标记(子字符串)替换,便生成了最终需要的业务数据(如网页)。

  3. “置换型”模板引擎实现简单,但其效率低下,无法满足高负载的应用需求(比如有海量 访问的网站),因此还出现了“解释型”模板引擎和“编译型”模板引擎等。

Thymeleaf(官网:https://www.thymeleaf.org/

  1. Thymeleaf 是面向 Web 和独立环境的现代服务器端 Java 模板引擎,能够处理 HTML、XML、 JavaScript、CSS 甚至纯文本。
  2. Thymeleaf 旨在提供⼀个优雅的、高度可维护的创建模板的方式。为了实现这一目标, Thymeleaf 建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板设计原型, 从而改善了设计的沟通,弥合了设计和开发团队之间的差距。
  3. Thymeleaf 从设计之初就遵循 Web 标准——特别是 HTML 5 标准,如果需要,Thymeleaf 允许创建完全符合 HTML 5 验证标准的模板。
  4. Spring Boot 体系内推荐使用 Thymeleaf 作为前端页面模板,并且 Spring Boot 2.0 中默认 使用 Thymeleaf 3.0,性能提升幅度很大。

特点

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

注意: 由于 Thymeleaf 使用了 XML DOM 解析器,因此它并不适合于处理大规模的 XML 文件。

表达式与常用标签

Thymeleaf 要输出数据,一般是通过表达式和标签配合实现(类似 EL+JSTL) 。

Thymeleaf 表达式共分为以下五类 (在之后的示例中可以看到如何使用):

1. 变量表达式:

  1. 变量表达式即 OGNL 表达式或 Spring EL 表达式。

  2. 变量表达式默认从 Model Attribute 中获取数据,进行赋值、输出、拼接等操作。

  3. 如果不想通过 th 标签而是简单地访问 Model 对象数据,或是想在 javascript 代码块里访 问 Model 中的数据,则要使用内联的方法。

1.变量表达式: ${...} 或 [[${...}]]

赋值:<span th:text="${stu.stuName}"></span>

拼接赋值:<span th:text="|Hello ${stu.stuName}!|"></span>

内联赋值:<span>[[${stu.stuName}]]</span>
内联方法:<script th:inline="javascript"></script>


<!-- 使用Session赋值时需要在值的前面加上session -->
示例:<span>[[${session.stu.stuName}]]</span>

2. 选择或星号表达式:*{…}

  1. 选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行
  2. 选择表达式与变量表达式有一个重要的区别 : 选择表达式计算的是选定的对象,而不是整个环境变量映射。简单来说就是指只要没有选择的对象,选择表达式与变量表达式的语法就是完全一致的!
  3. 在没有object对象选择的时候才可用简写,否则会报错。
<!-- 指定一个object对象然后即可使用选择表达式获取该对象中的值 -->
<div th:object="${session.student}">
        <p>欢迎:<span th:text="*{stuName}"></span></p>
</div>

<!-- 也可简写为如下代码 -->
<p>欢迎:<span th:text="*{session.student.stuName}"></span></p>

3. 文字国际化表达式:#{…}

文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties)。

注: 在使用前先将字符编码设置为utf-8,否则会乱码(在File–>Seetings–>File Encodings中设置)
在这里插入图片描述
先创建一个.properties的文件,在里面创建值:

# 在该文件中定义一个值(我这里的文件名为message_chinese.properties)
title=欢迎您

然后在application.properties文件中使用对应文件:

spring.messages.basename=message_chinese

最后就可以在页面中使用文字国际化表达式调用自己创建的值了:

<!-- 使用文字国际化表达式调用即可 -->
<h1 th:text="#{title}"></h1>

4. URL 表达式:@{…}

表单提交:<form th:action="@{/stu/User}" method="post">...</from>

超链接路径:<a th:href="@{/stu/User}" >...</a>
    
引入jQuery:<script th:src="@{/jquery-3.4.1.js}"></script>

5. 片段表达式:~{…}

Thymeleaf 3.0 引入了一种新型的表达式,作为一般 Thymeleaf 标准的语法表达式之一, 它就是:片段表达式。

它使用类似 ~{template::selector} 的语法,作用在 th:insert 和 th:replace 的内部。使用片段表达式支持引入片段的同时传参来构造目标页面,大大提高了代码复用的灵活度。

Thymeleaf 3.0 推荐使用 th:insert 替换 2.0 的 th:replace。th:insert 只是加载,th:replace 是替换。

常用标签

​ 除了以下这些标签还有很多标签,大家可以去官网进行了解。

在这里插入图片描述

逻辑控制标签 :

在这里插入图片描述
这里先给大家看一些逻辑控制标签的是使用案例,在后面的代码示例中也会使用到一些常用的标签。

  1. 条件判断(if/nuless)

    <!-- th:if、当条件成立时显示对应的内容 -->
    <h1>欢迎:<span th:if="${session.student.stuName==null}">123</span></h1>
    
    <!-- th:unless、与if相反,在当条件不成立时显示对应的内容 -->
    <h1>欢迎:<span th:unless="${session.student.stuName==null}">123</span></h1>
    
  2. switch 选择

    <!-- 与case一起使用,里面的值为条件 -->
    <div th:switch="${session.student.stuSex}">
        <p th:case="'男'">man</p>
    	<p th:case="'女'">woman</p>
    </div>
    
  3. for 循环

    <!-- 这里就只演示一下list遍历数据的方式 -->
    <tr>
        <th>用户ID</th>
        <th>用户名</th>
        <th>密码</th>
    </tr>
    <!-- Student 表示获取数据的集合,stu 表示循环变量 -->
    <tr th:each="stu,status :${Student}">
        <!-- 也可以写成<td th:text="${stu.stuId}">... -->
        <td>[[${stu.stuId}]]</td>	
        <td>[[${stu.stuName}]]</td>
        <td>[[${stu.stuPassword}]]</td>
    </tr>
    

    status 表示循环状态变量(也可以省略),属性包括 :

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

快速上手

创建项目

在这里插入图片描述

添加依赖(pom文件)

<dependencies>
        <!-- Spring Boot DataJPA 启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- Spring BootThymeleaf 模板引擎启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- Spring Boot web 启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.18</version>
        </dependency>

        <!-- 使lombor插件生效 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
</dependencies>
    
<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
</build>

添加配置信息(application.properties文件)

# 数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456

#关闭 Thymeleaf 的缓存,不然在开发过程中修改页面不会立刻生效需要重启,生产可配置为 true。
spring.thymeleaf.cache=false
    
# mysql方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
    
# 是否在控制台输出sql语句
spring.jpa.show-sql=true
    
# 格式化sql语句,让sql语句更加清晰易懂
spring.jpa.properties.hibernate.format_sql=true

配置实体类–>Dao层–>Service层–>Controller层

注:(此处省略实体类至controller层的创建与注解解析,不会的小伙伴可以先去看第三章)

案例

  1. 使用Thyeleaf模板引擎实现登录与显示所有用户信息的操作

       在Dao层继承JpaRepository<实体类类型,主键类型>, JpaSpecificationExecutor<实体类类型>后创建自定义方法:

//用户登录
public Student findByStuNameAndStuPassword(String stuName,String stuPassword);

​ 在Service接口中创建对应的方法,且在Service实现层中调用Dao层方法:

//Service接口
public interface StudentService {
    //用户登录
    public Student getLogin(String stuName,String stuPassword);
}
//Service实现
@Service
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentDao studentDao;
    
    //用户登录
    @Override
    public Student getLogin(String stuName, String stuPassword) {
        return studentDao.findByStuNameAndStuPassword(stuName,stuPassword);
    }
}

​ 在Controller层创建对应方法且调用Service层与Dao层(增删改需要用到Dao层提供的方法,这里只是演示所以直接省略业务逻辑层的代码直接调用dao层方法实现)

注: 因为 Thyeleaf 模板引擎是使用 html5 的格式编写的,不能像 jsp 那样直接页面跳转,所以在进入页面时需要通过controller层才能访问!

@Controller
@RequestMapping("stu")
public class StudentController {
    @Resource
    private StudentService studentService;
    //此处调用dao层是因为它继承之后会提供一些常用的增删改查的方法
    @Resource
    private StudentDao studentDao;

    //进入登录页面
    @GetMapping(value = "/login")
    public String login() {
        return "login";
    }

    //登录验证
    @PostMapping(value = "/toLogin")
    public String toLogin(String stuName, String stuPassword, Model model, HttpSession session) {
        Student student = studentService.getLogin(stuName, stuPassword);
        List<Student> list = studentDao.findAll();
        if (student != null) {
            //登录的用户使用session传入
            session.setAttribute("student", student);
            
            //全部的数据使用可以model传入
            model.addAttribute("StuList", list);
            return "/student/stu_main";
        } else {
            //如果输入有误则跳转至错误页面提示用户输入错误或者可以返回一段文字用于提示
            return "error";
        }
    }
}

在 resources 文件夹下的 templates 中创建需要使用的页面

登录页面(login): 用于用户登录与验证

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
    <form th:action="@{/stu/toLogin}" method="post">
        用户名:
        <input type="text" name="stuName" required>
        <br/>
        密码:
        <input type="password" name="stuPassword" required>
        <br/>
        <input type="submit" value="登录">
    </form>
</body>
</html>

主页面(main): 用于显示用户信息和配合各项操作

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>主页</title>
    <style>
        div {
            text-align: center;
            margin: 0 auto;
        }

        table {
            margin: 0 auto;
        }
    </style>
</head>
<body>
<div>
    <h1>欢迎:[[${session.student.stuName}]]</h1>
    搜索用户:<input type="text" name="stuName">
    <input type="button" th:onclick="'javascript:toSelect()'" value="搜索">
    <a th:href="@{/stu/Insert}">新增用户</a>
    <div id="stuTable">
        <table border="1">
            <tr>
                <th>用户ID</th>
                <th>用户名</th>
                <th>密码</th>
                <th>操作</th>
            </tr>
            <tr th:each="stu:${StuList}">
                <td>[[${stu.stuId}]]</td>
                <td>[[${stu.stuName}]]</td>
                <td>[[${stu.stuPassword}]]</td>
                <td>
                    <a th:href="@{/stu/Update(stuId=${stu.stuId})}">修改</a>
                    <a href="#" th:onclick="'javascript:toDelete('+this+','+${stu.stuId}+')'">删除</a>
                </td>
            </tr>
        </table>
    </div>
</div>
</body>
<script th:src="@{/jquery-3.4.1.js}"></script>
<script th:inline="javascript">
</script>
</html>

属性解析:

  1. xmlns:th=“http://www.thymeleaf.org” : 使用 Thymeleaf 的页面必须在 HTML 标签声明 Thymeleaf。
  2. th:each="stu:StuList"stu{StuList}":循环遍历;stu表示别名,StuList":循环遍历;stu表示别名,{StuList}表示Controller层保存的Model参数。此格式用于遍历 List 集合,如果是其他方式的循环遍历方法会有一点不一样,比如数组、Map等。
  3. “‘javascript:toInsert()’”:无参的点击事件;toInsert() 表示方法名。
  4. “‘javascript:toUpdate(’+this+’;’+${stu.stuId}+’)’”:带参的点击事件;参数不需要被包括起来,所以需要使用单引号与加号隔离开。

错误页面(error): 用于用户执行错误时跳转至该页面进行提示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>错误页面</title>
</head>
<body>
    <h1>系统正忙,请稍后再试</h1>
</body>
</html>

编写完运行之后在浏览器中输入中 http://localhost:8080/stu/login 即可进入登录页面。

  1. 新增用户

    ​ 因为继承了 JpaRepository ,所以我们就可以直接使用它内部所提供的方法。

    新增方法: save();返回的是对象类型,参数为对象类型,传值时 Id 切勿赋值,否则该方法效果为修改!

    ​ 在Controller层中编写跳转方法与新增方法

跳转方法的意义: 因为 thymeleaf 模板引擎是使用 html 格式编写的,所以不能像 jsp 一样直接在页面之间实现跳转(可以使用单击事件等方法),所以就需要在 Controller 层编写跳转方法。

	//跳转至新增用户页面
    @GetMapping(value = "/Insert")
    public String Insert() {
        return "student/stu_add";
    }

	//跳转至主页面
    @GetMapping(value = "/Main")
    public String Main(Model model) {
        List<Student> list = studentDao.findAll();
        model.addAttribute("StuList", list);
        return "student/stu_main";
    }

    //新增用户方法
    @PostMapping(value = "/toInsert")
    public String toInsert(Student student, Model model) {
        Student stu = studentDao.save(student);
        if (stu != null) {
            //新增成功后使用重定向返回主页,不使用重定向的话刷新一次就会执行一次新增方法!
            return "redirect:/stu/Main";
        } else {
            return "error";
        }
    }

编写html新增页面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>新增用户</title>
    <style>
        table{
            text-align: center;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <form th:action="@{/stu/toInsert}" method="post">
        <table>
            <tr>
                <th style="font-size: 20px;" colspan="2">新增用户信息</th>
            </tr>
            <tr>
                <th>用户名:</th>
                <td>
                    <input type="text" name="stuName" required>
                </td>
            </tr>
            <tr>
                <th>密码:</th>
                <td>
                    <input type="text" name="stuPassword" required>
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="提交">
                    <input type="reset" value="清空">
                    <input type="button" value="返回" onclick="history.go(-1)">
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

属性解析:

required:非空,此文本框必须填写数据,否则无法提交。

submit:提交按钮,此处为提交表单。

reset:重置按钮,将输入的值全部清除。

history.go(-1):返回上一级。

以上是HTML的一些属性。

  1. 修改用户

    在application.properties配置文件中添加如下配置

    # 添加该配置后即可使用put或delete提交方式
    spring.mvc.hiddenmethod.filter.enabled=true
    

    Controller层(需要使用到两个方法,一个用于查询用户信息,一个用户信息)

    	//跳转至修改用户页面
        @GetMapping(value = "/Update")
        public String Update(Integer stuId, Model model) {
            Student student = studentDao.getOne(stuId);
            model.addAttribute("student", student);
            return "student/stu_mod";
        }
    
        //修改用户方法
        @PutMapping(value = "/toUpdate")
        public String toUpdate(Student student, Model model) {
            Student stu = studentDao.save(student);
            List<Student> list = studentDao.findAll();
            if (stu != null) {
                //返回主页面是重新加载一遍数据,即可看到修改后的用户信息
                model.addAttribute("StuList", list);
                return "student/stu_main";
            } else {
                return "error";
            }
        }
    

    html修改用户页面

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>修改用户</title>
        <style>
            table {
                text-align: center;
                margin: 0 auto;
            }
        </style>
    </head>
    <body>
    <form th:action="@{/stu/toUpdate(stuId=${student.stuId})}" method="post">
    	<!-- 必须要加上 -->
        <input hidden value="put" name="_method">
        
        <table>
            <tr>
                <th style="font-size: 20px;" colspan="2">修改用户信息</th>
            </tr>
            <tr>
                <th>用户名:</th>
                <td>
                    <input type="text" name="stuName" th:value="${student.stuName}" required>
                </td>
            </tr>
            <tr>
                <th>密码:</th>
                <td>
                    <input type="text" name="stuPassword" th:value="${student.stuPassword}" required>
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="保存">
                    <input type="button" value="返回" onclick="history.go(-1)">
                </td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    
  2. 删除用户(ajax)

    html主页面的删除单击方法实现

    function toDelete(th, stuId) {
        	//判断是否需要删除,避免手误删除重要信息
            if (confirm("确定要删除当前用户吗?")) {
                $.ajax({
                    url: "/stu/toDelete/" + stuId,
                    data: {_method: "DELETE"},
                    type: "POST",
                    success: function (data) {
                        if (data > 0) {
                            alert("删除成功!");
                            //执行以下语句把对呀的用户移除
                            $(th).parent().parent().remove();
                        } else {
                            alert("删除失败!");
                        }
                 }
                });
         }
        }
    

    controller层实现方法

    //删除
    @DeleteMapping(value = "/toDelete/{stuId}")
    public void toDelete(@PathVariable("stuId") Integer stuId, HttpServletResponse response) throws IOException {
        //提供的删除方法是void类型,所以直接调用即可
        studentDao.deleteById(stuId);
        
        //返回参数给ajax进行判断
        PrintWriter out = response.getWriter();
        out.print(1);
    }
    
  3. 查询用户(模糊查询)

    接下来就是一个局部刷新的页面搜索,使用渲染的方式实现。

    首先,在Dao层中添加自定义方法

    //对用户进行模糊查询
    public List<Student> findByStuNameLike(String stuName);
    

    然后,直接在控制层中调用dao层中创建的自定义方法

    //用户查询
    @PostMapping(value = "/toSelect")
    public String toSelect(String stuName,Model model){
        List<Student> list = studentDao.findByStuNameLike("%"+stuName+"%");
        model.addAttribute("StuList",list);
        //执行完后返回至渲染页面
    	return "student/stu_main_ajax";
    }
    

    在主页面中加入ajax

    //用户查询
    function toSelect() {
    	//第一个值为路径,第二个值为传入后台的值
    	$("#stuTable").load("/stu/toSelect",{"stuName":$("input[name=stuName]").val()});
    }
    

    创建渲染页面,将要渲染的数据从主页面中复制过去,这里演示直接使用div把table包裹起来,然后渲染整个table

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
        <style>
            div {
                text-align: center;
                margin: 0 auto;
            }
    
            table {
                margin: 0 auto;
            }
        </style>
    </head>
    <body>
    <div id="stuTable">
        <table border="1">
            <tr>
                <th>用户ID</th>
                <th>用户名</th>
                <th>密码</th>
                <th>操作</th>
            </tr>
            <tr th:each="stu:${StuList}">
                <td>[[${stu.stuId}]]</td>
                <td>[[${stu.stuName}]]</td>
                <td>[[${stu.stuPassword}]]</td>
                <td>
                    <a th:href="@{/stu/Update(stuId=${stu.stuId})}">修改</a>
                    <a href="#" th:onclick="'javascript:toDelete('+this+','+${stu.stuId}+')'">删除</a>
                </td>
            </tr>
        </table>
    </div>
    

以上就是简单的增删改查啦,记得多敲几遍加深影响哦QAQ

标签:Ch05,Spring,Boot,用户,stu,Thymeleaf,表达式,模板,页面
来源: https://blog.csdn.net/weixin_44552039/article/details/104804182