Springboot做了自动处理,通过post方式提交表单的时候,需要有一个实体类,去接收表单传递的数据内容,在对象的属性读取中,Thymeleaf 提供了两种方式:1、直接通过${userInfo.username} ,这种实体bean + 属性的方式;2、通过选择表达式*{username}的这种方式。表单input中的name属性值要和实体类的属性保持一致
Spring Validation
在实际的工作中对于数据的保存是离不开数据验证的,比如说name必须要输入,isbn 必须要输入等等校验规则,Spring 对于数据验证支持的也非常好,我们可以借助Spring Validation来处理表单数据的验证。
Validation注解
JSR 380定义了-些注解用于做数据校验,这些注解可以直接设置在Bean的属性上
|注解|说明|备注|
@NotNull | 不允许为null对象 | |
@AssertTrue | 是否为true | |
@Size | 约定字符串的长度 | |
@Min | 字符串的最小长度 | |
@Max | 字符串的最大长度 | |
是否是邮箱格式 | ||
@NotEmpty | 不允许为null或者为空,可以用于判断字符串、集合,比如Map、数组、List | |
@NotBlank | 不允许为null和空格 |
注意:
大多数情况下,建议使用NotEmpty替代NotNull、NotBlank
package com.bookstore.model;
import javax.validation.constraints.*;
public class User {
@NotEmpty(message = "名称不能为 null")
private String name;
@Min(value = 18, message = "你的年龄必须大于等于18岁")
@Max(value = 150, message = "你的年龄必须小于等于150岁")
private int age;
@NotEmpty(message = "邮箱必须输入")
@Email(message = "邮箱不正确")
private String email;
// standard setters and getters
}
校验的注解是可以累加的,如上面的@Min和@Max,系统会按顺序执行校验,任何一条校验触发就会抛出校验错误到上下文中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>添加用户</title>
<style>
.error {
color: red;
}
</style>
</head>
<body>
<h2>添加用户</h2>
<form action="/user/save" th:object="${user}" method="POST">
<div th:classappend="${#fields.hasErrors('name')} ? 'error' : ''">
<label>用户名称:</label>
<input type="text" th:field="*{name}">
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></p>
</div>
<div th:classappend="${#fields.hasErrors('age')} ? 'error' : ''">
<label>年龄:</label>
<input type="text" th:field="*{age}">
<p th:if="${#fields.hasErrors('age')}" th:errors="*{age}"></p>
</div>
<div th:classappend="${#fields.hasErrors('email')} ? 'error' : ''">
<label>邮箱:</label>
<input type="text" th:field="*{email}">
<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></p>
</div>
<div th:classappend="${#fields.hasErrors('mobile')} ? 'error' : ''">
<label>手机号码:</label>
<input type="text" th:field="*{mobile}">
<p th:if="${#fields.hasErrors('mobile')}" th:errors="*{mobile}"></p>
</div>
<div>
<button type="submit">保存</button>
</div>
</form>
</body>
</html>
说明:
1.control类中的方法药先new一个实例对象传到页面去,如下代码中的addUser方法。
2.form表单里的th:object=“${user}”用于替换对象,使用了这个就不需要每次都编写user. xxx,可以直接操作XXX
3.${#fields.hasErrors(‘key’)} 这个语法是专门为验证场景提供的,这里的 key就是对象的属性名称,比如User对象的name、age、 email 等。
4.标签里的th:errors,用于显示错误信息。
5.里的th:classappend支持动态管理样式
6.里的th:field可以显示上一次输入的内容。
package com.bookstore.control;
import com.bookstore.model.User;
import com.bookstore.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;
import java.util.List;
@Controller
public class UserControl {
@Autowired
private UserService userService;
@GetMapping("/user/add.html")
public String addUser(Model model) {
User user = new User();
model.addAttribute("user", user);
return "user/addUser";
}
@PostMapping("/user/save")
public String saveUser(@Valid User user, BindingResult errors) {
if (errors.hasErrors()) {
// 如果校验不通过,返回用户编辑页面
return "user/addUser";
}
userService.saveUser(user);
// 校验通过,返回成功页面
return "redirect:/user/list.html";//跳转到@GetMapping("/user/list.html")
}
@GetMapping("/user/list.html")
public String list(Model model) {
List<User> users = userService.getUsers();
model.addAttribute("users", users);
return "user/list";
}
}
说明:
redirect:这个用于跳转到某-一个页面网址,如果是同一个域名,你可以省略域名,直接写path, 比如这里的/user/list. html你也可以跳转到某个网站,比如return “redirect: https: //www. baidu. com”;大体上所有的增加、查询行为都是这样的流程。