SpringBoot2 学习笔记08 Validation 参数校验
系列 - SpringBoot2 学习笔记
目录
更新记录 20241122:重构系列
1 简单案例
https://github.com/eezd/cli-template/blob/main/springboot2-template/eezd-common/pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>- 新建一个名为
PersonDTO的文件
package com.eezd.main.web.dto;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class PersonDTO {
@NotBlank(message = "name 姓名不能为空")
private String name;
@NotNull(message = "age 年龄不能为空")
@Min(value = 0, message = "年龄不能小于0")
private Integer age;
@NotNull(message = "gender 性别不能为空")
private Integer gender;
}- 创建一个 Controller
@PostMapping("/test1")
public Object save(@Validated @RequestBody PersonDTO person, BindingResult bindingResult) {
System.out.println(bindingResult);
if (bindingResult.hasErrors()) {
List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
Map<String, String> map = new HashMap<>(fieldErrorList.size());
fieldErrorList.forEach(item -> {
String field = item.getField(); // 字段名
String message = item.getDefaultMessage(); // 错误信息
map.put(field, message);
});
return map;
} else {
// 伪代码
// personService.save(person);
}
return "YES";
}- 发送一个
curl请求
curl --location --request POST 'http://localhost:8080/test1' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "张三"
}'- 返回
{
"gender": "gender 性别不能为空",
"age": "age 年龄不能为空"
}2 全局异常捕获
如果你不希望每次都在开头写那堆捕获代码,那就可以通过全局异常捕获
package com.eezd.main.core.exception;
/**
* 全局异常处理器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 自定义验证异常
*/
@ExceptionHandler(BindException.class)
public AjaxResult handleBindException(BindException e) {
log.error(e.getMessage());
String message = e.getAllErrors().get(0).getDefaultMessage();
return AjaxResult.error(message);
}
/**
* 自定义验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error(e.getMessage());
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return AjaxResult.error(message);
}
}- 创建一个 Controller
@PostMapping("/test2")
public AjaxResult test(@Validated @RequestBody PersonDTO person) {
return AjaxResult.success("YES");
}- 使用 curl 测试
curl --location --request POST 'http://localhost:8080/test2' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "张三"
}'3 注解
3.1 判断为空
@NotBlank: 不为 null, 去除前后空格后长度不为 0- 支持类型:
CharSequence(字符串)
- 支持类型:
@NotEmpty: 不为 null, 且长度不为 0- 支持类型:
CharSequence,Collection,Map,Arrays
- 支持类型:
@NotBlank和@NotEmpty的区别是: 前者会对字符串进行trim()操作删除空格, 而后者是直接对长度进行判断。
@Null: 限制元素是 null@NotNull: 限制元素不是 null@AssertFalse: 限制元素是 false@AssertTrue: 限制元素是 true
3.2 限制长度
下面是限制长度
@Length(min=下限, max=上限):支持验证字符串长度@Size(min=最小值, max=最大值): 支持字符串,集合,映射和数组。
3.3 限制数值
限制大小
@Max(value=)和@Min(value=): 限制 整数 的是否大于等于/小于等于@Range(min=最小值, max=最大值): 限制数字范围@DecimalMax(value=n)和@DecimalMin(value=n): 限制 浮点数@Digits(integer=整数位数, fraction=小数位数): 限制整数位数和小数位数上限
3.4 时间检查
@Future: 必须是将来的日期@FutureOrPresent: 必须是将来的日期, 或当前日期@Past: 必须是过去的日期@PastOrPresent: 必须是过去的日期, 或当前日期
3.5 其他
- @Email 检查是否一个合法的邮箱地址
- @Pattern 检查是否符合指定的正则规则
@Data
public class PersonDTO {
@NotBlank(message = "name 姓名不能为空")
private String name;
@NotNull(message = "age 年龄不能为空")
@Min(value = 0, message = "年龄不能小于0")
private Integer age;
@NotNull(message = "gender 性别不能为空")
private Integer gender;
@Email(regexp = RegularConstant.EMAIL, message = "email 邮箱格式不正确")
private String email;
@Pattern(regexp = RegularConstant.PHONE, message = "phone 手机号格式不正确")
private String phone;
@Past(message = "birthday 生日日期有误")
private LocalDate birthday;
}- 接下来是限制 email 和 phone
public class RegularConstant {
public static final String EMAIL = "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
public static final String PHONE = "^1[0-9]{10}$";
}4 分组校验
- 不同请求使用不同的校验规则, 通过组别进行分开
@Data
public class Person {
@NotBlank(message = "name 姓名不能为空", groups = AddGroup.class)
private String name;
@NotNull(message = "age 年龄不能为空", groups = UpdateGroup.class)
@Min(value = 0, message = "年龄不能小于0")
private Integer age;
@NotNull(message = "gender 性别不能为空", groups = {AddGroup.class, UpdateGroup.class})
private Integer gender;
@NotBlank(message = "email 邮箱不能为空", groups = Default.class)
@Email(regexp = RegularConstant.EMAIL, message = "email 邮箱格式不正确", groups = Default.class)
private String email;
@NotBlank(message = "phone 手机号不能为空", groups = UpdateGroup.class)
@Pattern(regexp = RegularConstant.PHONE, message = "phone 手机号格式不正确")
private String phone;
@Past(message = "birthday 生日日期有误")
private LocalDate birthday;
}- 给
@Validated添加上组别就可以验证了
@PostMapping("/test2")
public AjaxResult test(@Validated(AddGroup.class) @RequestBody PersonDTO person) {
return AjaxResult.success("YES");
}