SpringBoot后端数据校验实战

本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:SpringBoot后端数据校验实战

一般我们会在Controller的接口中对前端传递的参数做数据校验,这是一个后端开发人员的基本素养

在SpringBoot项目中,为了不让一大堆复杂的校验代码入侵业务逻辑,通常会用校验注解来简化代码

要使用校验注解,首先要引入hibernate-validator依赖

<!--JSR303数据校验支持-->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>

如果是Springboot工程,那么引入spring-boot-starter-web后就会自动引入hibernate-validator

常用校验注解

可以在需要校验的参数上标注下列校验注解

限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

1.空与非空检查

注解 支持Java类型 说明
@Null Object 为null
@NotNull Object 不为null
@NotBlank CharSequence 不为null,且必须有一个非空格字符
@NotEmpty CharSequence、Collection、Map、Array 不为null,且不为空(length/size>0)

2.Boolean值检查

注解 支持Java类型 说明 备注
@AssertTrue boolean、Boolean 为true 为null有效
@AssertFalse boolean、Boolean 为false 为null有效

3.日期检查

注解 支持Java类型 说明 备注
@Future Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 验证日期为当前时间之后 为null有效
@FutureOrPresent Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 验证日期为当前时间或之后 为null有效
@Past Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 验证日期为当前时间之前 为null有效
@PastOrPresent Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 验证日期为当前时间或之前 为null有效

4.数值检查

注解 支持Java类型 说明 备注
@Max BigDecimal、BigInteger,byte、short、int、long以及包装类 小于或等于 为null有效
@Min BigDecimal、BigInteger,byte、short、int、long以及包装类 大于或等于 为null有效
@DecimalMax BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 小于或等于 为null有效
@DecimalMin BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 大于或等于 为null有效
@Negative BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 负数 为null有效,0无效
@NegativeOrZero BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 负数或零 为null有效
@Positive BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 正数 为null有效,0无效
@PositiveOrZero BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 正数或零 为null有效
@Digits(integer = 3, fraction = 2) BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 整数位数和小数位数上限 为null有效

5.其他

注解 支持Java类型 说明 备注
@Pattern CharSequence 匹配指定的正则表达式 为null有效
@Email CharSequence 邮箱地址 为null有效,默认正则 '.*'
@Size CharSequence、Collection、Map、Array 大小范围(length/size>0) 为null有效

6.hibernate-validator扩展注解

注解 支持Java类型 说明
@Length String 字符串长度范围
@Range 数值类型和String 指定范围
@URL String URL地址验证

基础校验

1.基本数据类型校验

如果Controller的接口方法中需要校验的参数是基本数据类型,如StringInteger等非封装的对象,那么可以按照如下步骤:

  1. 在Controller上添加@Validated
  2. 在Controller的接口方法中给需要校验的参数前面添加校验注解
@RestController
@RequestMapping("validate")
@Validated
public class ValidateController {
   
    @GetMapping("test")
    public String test(@NotBlank(message = "名称不能为空") String name) {
   
        return "success";
    }
}

请求参数不传name,校验不通过,会抛出javax.validation.ConstraintViolationException异常

2.javabean校验

如果Controller的接口方法中需要校验的参数是封装的javabean,想要校验bean中的部分属性,那么可以按照如下步骤:

  1. 给javabean中需要校验属性上添加校验注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   
    // 字符串长度校验,长度必须在2~5之间
    @Length(min = 2, max = 5)
    private String name;

    private Integer age;

    @JsonFormat(pattern = "yyyy-MM-dd")
    @Past  // 日期校验,日期必须是过去的一个日期
    private Date birth;
}
  1. 在Controller的请求处理方法参数声明中,在需要校验的Bean的形参前面加上@Valid注解,并在该Bean的形参后面紧跟着声明一个BindingResult类型的参数(注意,中间不能夹杂任何其他类型的参数),这样校验的结果就会保存在BindingResult对象中
@RestController
@RequestMapping("validate")
public class ValidateController {
   
    @PostMapping("test1")
    public String testValidate(@RequestBody @Valid User user, BindingResult bindingResult){
   
        System.out.println(user);
        System.out.println(bindingResult);
        return "success";
    }
}

我们故意传入一些校验不通过的数据进行测试

name和birth的校验将会不通过,控制台打印输出如下

User(name=baobao, age=18, birth=Sun Jul 25 08:00:00 CST 2021)
org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'user' on field 'name': rejected value [baobao]; codes [Length.user.name,Length.name,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.name,name]; arguments []; default message [name],5,2]; default message [长度需要在25之间]
Field error in object 'user' on field 'birth': rejected value [Sun Jul 25 08:00:00 CST 2021]; codes [Past.user.birth,Past.birth,Past.java.util.Date,Past]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.birth,birth]; arguments []; default message [birth]]; default message [需要是一个过去的时间]

BindingResult对象中包含了校验错误信息

注意:

  • 如果我们在Controller方法参数中不加BindingResult对象捕获校验失败信息,那么校验失败信息会以org.springframework.web.bind.MethodArgumentNotValidException异常形式被异常解析器处理

    2021-07-23 23:27:33.372  WARN 4352 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String com.baobao.springboot.validate.controller.ValidateController.testValidate(com.baobao.springboot.validate.entity.User) with 2 errors: [Field error in object 'user' on field 'birth': rejected value [Sun Jul 25 08:00:00 CST 2021]; codes [Past.user.birth,Past.birth,Past.java.util.Date,Past]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.birth,birth]; arguments []; default message [birth]]; default message [需要是一个过去的时间]] [Field error in object 'user' on field 'name': rejected value [baobao]; codes [Length.user
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值