模板布局
公共部分通常定义为模板布局:如页眉,页脚,公共导航栏、菜单等。
模板布局定义方法
布局页中用
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 属性
- 创建html文件(如footer.html),直接通过 id 属性定义一个片段
<footer id="copy">
© 2021 Hello Dust, here is your footer.
</footer>
- 其他页面通过 #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) | 被注释的元素必须符合指定的正则表达式 |
被注释的元素必须是电子邮箱地址 | |
@Length(min=, max=) | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串的必须非空 |
@Range(min=, max=) | 被注释的元素必须在合适的范围内 |
@NotBlank | 被注释的字符串的必须非空 |
@URL(protocol=, host=, port=,regexp=, flags=) | 被注释的字符串必须是一个有效的url |