模板布局

公共部分通常定义为模板布局:如页眉,页脚,公共导航栏、菜单等。

模板布局定义方法

布局页中用 th:fragment 定义模板片段,其他页面用 th:insert 引用片段

例如:footer.html,通过 th:fragment 定义一个模板片段

<footer th:fragment="copy"></footer>

其他页面通过 th:insert 引用片段:

  • 标准形式:
<div th:insert = "~{ footer :: copy }"></div>
  • 简写形式:
<div th:insert="footer :: copy"></div>

示例:(项目需要参考本人[JAVA EE]系列前文创建,请自行去本人主页查阅)

  • 在th文件夹下新建一个footer.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Footer</title>
    </head>
    <body>
        <footer th:fragment="copy">
            © 2021 Hello Dust, here is your footer.
        </footer>
    </body>
</html>
  • 修改index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div th:insert="~{ th/footer::copy }"></div>
    </body>
</html>
  • 运行

th:insert 、th:replace、 th:include 区别

这三个运行结果表面看上去是相同的
<div th:insert="~{ th/footer::copy }"></div>
<div th:replace="~{ th/footer::copy }"></div>
<div th:include="~{ th/footer::copy }"></div>


带参数的引用片段

示例:

  • footer.html
<footer th:fragment="copy(name)">
      © 2021 Hello Dust, here is your footer.
      <p th:text="'Authorized by ' + ${name}"></p>
</footer>
  • index.html
<body>
    <div th:insert="~{ th/footer::copy(${stuList[0].name}) }"></div>
</body>
  • 附上我的控制器:
  • TestController.java
package com.example.demo.controller;

import com.example.demo.bean.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class TestController {
   

    @RequestMapping("/th")
    public String index(Model model) {
   
        List<Student> stuList = new ArrayList<Student>();
        stuList.add(new Student(2019001, "小明"));
        stuList.add(new Student(2019002, "小丽"));
        stuList.add(new Student(2019003, "小王"));
        model.addAttribute("stuList", stuList);

        return "th/index";
    }
}
  • bean包里的student.java
package com.example.demo.bean;

public class Student {
   
    private Integer id;  //学号
    private String name;  //姓名

    public Student() {
   
    }

    public Student(Integer id, String name) {
   
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
   
        return id;
    }

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

    public String getName() {
   
        return name;
    }

    public void setName(String name) {
   
        this.name = name;
    }
}
  • 项目结构:

    运行结果:
  • 在index.html里把[0]改成[1],就会变成:
  • 说明此处是传参。

模板布局另一种定义方法:通过 id 属性

  1. 创建html文件(如footer.html),直接通过 id 属性定义一个片段
<footer id="copy">
	© 2021 Hello Dust, here is your footer.
</footer>
  1. 其他页面通过 #id 引用片段(没忘记#选择器是id选择器吧?)
<div th:insert="~{ footer :: #copy }"></div> 

表单验证

表单输入的信息通常需要进行验证,以及提供错误信息反馈。

验证相关的标签

(1)单个字段错误信息提示:th:errors 标签

<span th:if="${#fields.hasErrors('stu.name')}" th:errors="${stu.name}"></span>

#fields.hasErrors():指定字段是否有返回的错误信息
th:errors ():显示指定字段返回来的错误信息
此例绑定的是stu.name属性字段

(2)显示所有错误信息:遍历 #fields.errors()

<ul th:if="${#fields.hasErrors('stu.*')}">
	<li th:each="err:${#fields.errors('stu.*')}" th:text="${err}"></li>
</ul>

#fields.errors():获取指定字段返回的错误信息
stu.*:表示stu对象的所有属性字段


(1)添加验证依赖,添加之后要重启IDEA

  • pom.xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

(2)在实体类属性中添加约束

  • Student.java
public class Student {
   
	@Min(value=2020001,message="最小值2020001")
	@Max(value=2020999,message="最大值2020999")
	private long id;//主键.
	@NotBlank(message="姓名不能为空")
	@Length(min=5,max=20,message="姓名长度为5-20个字符")
	private String name;
	…其他代码不变
}

(3)添加控制器代码

  • TestController.java
@Controller
public class TestController {
   

    @RequestMapping("/th")
    public String index(Model model) {
   
        List<Student> stuList = new ArrayList<Student>();
        stuList.add(new Student(2019001, "小明"));
        stuList.add(new Student(2019002, "小丽"));
        stuList.add(new Student(2019003, "小王"));
        model.addAttribute("stuList", stuList);

        return "th/index";
    }

    @RequestMapping("/edit")
    public String edit( Model model){
   
        Student s=new Student(2019001,"小明");
        model.addAttribute("stu",s);
        return "th/form";
    }

    @RequestMapping(value="/save", method = RequestMethod.POST)
    public String save( @ModelAttribute("stu") @Validated Student stu,
                        BindingResult bindingResult,
                        Model model){
   
        if( bindingResult.hasErrors() ){
   
            return "th/form";
        }
        model.addAttribute("new_stu",stu);
        return "th/save"; //save.html略
    }

}
  • form.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form</title>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

    <form th:action="@{/save}" method="post" th:object="${stu}">
        <div>
            <label for="id">学号</label>
            <input type="text" id="id" th:field="*{id}" placeholder="请输入学号">
            <span th:if="${#fields.hasErrors('id')}" th:errors="*{id}" class="warn"></span>
        </div>
        <div>
            <label for="name">姓名</label>
            <input type="text" id="name" th:field="*{name}" placeholder="请输入姓名">
            <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="warn"></span>
        </div>
        <button id="btn" type="submit">保存</button>
        <div>
            <ul th:if="${#fields.hasErrors('*')}" class="warn">
                <li th:each="err:${#fields.errors('*')}" th:text="${err}" ></li>
            </ul>
        </div>
    </form>

</body>
</html>
  • 写一个save.html,不然符合要求会报错
<!DOCTYPE html>
<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <title>Save</title>
	</head>
	<body>
	    <p>saved~</p>
	</body>
</html>
  • 运行结果:




常用校验注解

注解 作用
@NotNull 被注释的元素必须不为 null
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是电子邮箱地址
@Length(min=, max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=, max=) 被注释的元素必须在合适的范围内
@NotBlank 被注释的字符串的必须非空
@URL(protocol=, host=, port=,regexp=, flags=) 被注释的字符串必须是一个有效的url