SpringBoot - 后端数据校验的实现(附样例)
对于数据校验,Spring Boot 也提供了相关的自动化配置解决方案,下面通过样例进行演示。
一、普通校验
1,添加依赖
首先编辑项目的 pom.xml 文件,添加数据校验相关的依赖。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2,创建校验出错的提示文件
在 resources 目录下创建一个 ValidationMessages.properties 文件(默认的创建校验出错的提示文件),里面内容如下:user.name.size=用户名长度介于5到10个字符之间
user.address.notnull=用户地址不能为空
user.age.size=年龄输入不正确
user.email.notnull=邮箱不能为空
user.email.pattern=邮箱格式不正确
3,数据校验配置
接下来创建一个 User 类,并配置相关的数据校验:@NoArgsConstructor @Setter @Getter public class User { // @Size 注解表示一个字符串的长度或者一个集合的大小,必须在某一个范围中 @Size(min = 5, max = 10, message = "{user.name.size}") private String name; // @NotEmpty 注解表示该字段不能为空 @NotEmpty(message = "{user.address.notnull}") private String address; // @DecimalMin 注解表示对应属性值的下限 @DecimalMin(value = "1", message = "{user.age.size}") // @DecimalMax 注解表示对应属性值的上限 @DecimalMax(value = "200", message = "{user.age.size}") private Integer age; // @Email 注解表示对应属性格式是一个 Email @Email(message = "{user.email.pattern}") // @NotNull 注解表示该字段不能为null @NotNull(message = "{user.email.notnull}") private String email; }
4,Controller 配置
接下来创建一个 Controller,给 User 参数添加 @Validated 注解,表示需要对该参数做校验,后面的 BindingResult 参数表示在校验出错时保存的出错信息。@RestController public class HelloController { @PostMapping("/user") public List<String> addUser(@Validated User user, BindingResult result) { List<String> errors = new ArrayList<>(); // 如果 BindingResult 的 hasErrors 方法返回true,则表示有错误信息 if (result.hasErrors()) { List<ObjectError> allErrors = result.getAllErrors(); /// 遍历错误信息,返回给前端 for (ObjectError error : allErrors) { errors.add(error.getDefaultMessage()); } } return errors; } }
5,运行测试
(1)启动项目后,我们如果直接访问“/user”接口,则返回如下信息:二、分组校验
有的时候,我们在某一个实体类中定义了很多校验规则,但是在某一次业务处理中,并不需要这么多校验规则,此时就可以使用分组校验。具体步骤如下。1,创建分组接口
首先创建两个分组接口:public interface ValidationGroup1 { } public interface ValidationGroup2 { }
2,在实体类中添加分组信息
这次在注解中添加了 groups 属性,表示该校验规则所属的分组:@NoArgsConstructor @Setter @Getter public class User { // @Size 注解表示一个字符串的长度或者一个集合的大小,必须在某一个范围中 @Size(min = 5, max = 10, message = "{user.name.size}", groups = ValidationGroup1.class) private String name; // @NotEmpty 注解表示该字段不能为空 @NotEmpty(message = "{user.address.notnull}", groups = ValidationGroup2.class) private String address; // @DecimalMin 注解表示对应属性值的下限 @DecimalMin(value = "1", message = "{user.age.size}") // @DecimalMax 注解表示对应属性值的上限 @DecimalMax(value = "200", message = "{user.age.size}") private Integer age; // @Email 注解表示对应属性格式是一个 Email @Email(message = "{user.email.pattern}") // @NotNull 注解表示该字段不能为null @NotNull(message = "{user.email.notnull}", groups = ValidationGroup2.class) private String email; }
3,在 Controller 中指定校验分组
接下来在 @Validated 注解中指定校验分组,这里的 @Validated(ValidationGroup2.class) 表示这里的校验使用 ValidationGroup2 分组的校验规则(只校验用户地址、邮箱地址是否为空):@RestController public class HelloController { @PostMapping("/user") public List<String> addUser(@Validated(ValidationGroup2.class) User user, BindingResult result) { List<String> errors = new ArrayList<>(); // 如果 BindingResult 的 hasErrors 方法返回true,则表示有错误信息 if (result.hasErrors()) { List<ObjectError> allErrors = result.getAllErrors(); /// 遍历错误信息,返回给前端 for (ObjectError error : allErrors) { errors.add(error.getDefaultMessage()); } } return errors; } }
4,运行测试
附:校验注解汇总
上面的样例只是演示了几个常见的校验注解,实际上校验注解远不止这几个,下面是完整的校验注解参考表。
验证注解 |
验证的数据类型 |
说明 |
空检查 |
||
@Null |
任意类型 |
验证注解的元素值是 null |
@NotNull |
任意类型 |
验证注解的元素不是 null |
@NotBlank |
CharSequence 子类型(CharBuffer、String、StringBuffer、StringBuilder) |
验证注解的元素值不为空(不为 null、去除首尾空格后长度不为 0),不同于 @NotEmpty,@NotBlank 只应用于字符串且在比较时会去除字符串的首尾空格 |
@NotEmpty |
CharSequence 子类型、Collection、Map、数组 |
验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0) |
Boolean检查 |
||
@AssertFalse |
Boolean,boolean |
验证注解的元素值是 false |
@AssertTrue |
Boolean,boolean |
验证注解的元素值是 true |
长度检查 |
||
@Size(min=下限, max=上限) |
字符串、Collection、Map、数组等 |
验证注解的元素值的在 min 和 max(包含)指定区间之内,如字符长度、集合大小 |
@Length(min=下限, max=上限) |
CharSequence 子类型 |
验证注解的元素值长度在 min 和 max 区间内 |
日期检查 |
||
@Past |
java.util.Date,java.util.Calendar,Joda-Time 类库的日期类型 |
验证注解的元素值(日期类型)比当前时间早 |
@Future |
与 @Past 要求一样 |
验证注解的元素值(日期类型)比当前时间晚 |
@PastOrPresent |
与 @Past 要求一样 |
验证注解的元素值(日期类型)比当前时间早,或者是当前时间 |
@FutureOrPresent |
与 @Past 要求一样 |
验证注解的元素值(日期类型)比当前时间晚,或者是当前时间 |
数值检查 |
||
@MIN(value=值) |
BigDecimal,BigInteger, byte,short, int, long,等任何 Number 或 CharSequence(存储的是数字)子类型 |
验证注解的元素值大于等于 @Min 指定的 value 值 |
@MAX(value=值) |
和 @Min 要求一样 |
验证注解的元素值小于等于 @Max 指定的 value 值 |
@DecimalMin(value=值) |
和 @Min 要求一样 |
验证注解的元素值大于等于 @ DecimalMin 指定的 value 值 |
@DecimalMax(value=值) |
和 @Min 要求一样 |
验证注解的元素值小于等于 @ DecimalMax 指定的 value 值 |
@Digits(integer=整数位数, fraction=小数位数) |
和 @Min 要求一样 |
验证注解的元素值的整数位数和小数位数上限 |
@Range(min=最小值, max=最大值) |
BigDecimal,BigInteger,CharSequence,byte,short,int,long等原子类型和包装类型 |
验证注解的元素值在最小值和最大值之间 |
@Negative |
和 @Range 要求一样 |
验证注解的元素必须是负数 |
@NegativeOrZero |
和 @Range 要求一样 |
验证注解的元素必须是负数或 0 |
@Positive |
和 @Range 要求一样 |
验证注解的元素必须是正数 |
@PositiveOrZero |
和 @Range 要求一样 |
验证注解的元素必须是正数或 0 |
其他检查 |
||
@Valid |
任何非原子类型 |
指定递归验证关联的对象;如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加 @Valid 注解即可级联验证 |
@Pattern(regexp=正则表达式,flag=标志的模式) |
CharSequence 的子类型 |
验证注解的元素值与指定的正则表达式匹配 |
@Email(regexp=正则表达式,flag=标志的模式) |
CharSequence 的子类型 |
验证注解的元素值是 Email,也可以通过 regexp 和 flag 指定自定义的 email 格式 |
@CreditCardNumber |
CharSequence 的子类型 |
验证注解元素值是信用卡卡号 |
@ScriptAssert(lang= ,script=) |
业务类 |
校验复杂的业务逻辑 |