认识@Validated 和 @Valid

对于web应用来说,对方法参数的校验是十分重要的,参数校验的是否全面,直接决定整个方法的健壮性。
除了使用麻烦的if判断校验参数,还可以使用@Validated 和 @Valid注解来进行优雅地参数校验,让参数校验和写诗一样优雅。

@Validated 和 @Valid依赖引入

首先,我们来了解一下@Validated 和 @Valid 的区别。
在这里插入图片描述
虽然@Validated 和 @Valid 的提供者不同,但是两者都是由hibernate-validator来提供实现的,可以理解为@Validated是Spring对@Valid 的封装,增强了其功能。

所以,如果需要使用@Validated 和 @Valid注解来进行参数校验,则必须引入如下依赖:

<dependency>  
    <groupId>org.hibernate</groupId>  
    <artifactId>hibernate-validator</artifactId>  
    <version>6.0.1.Final</version>  
</dependency>

需要注意的是:如果spring-boot版本小于2.3.x,spring-boot-starter-web会自动传入hibernate-validator依赖。否则需要手动引入依赖。
另外,如果写法正确,但是校验机制没有生效,那么可能是hibernate-validator依赖的版本不对,可以百度查询当前Spring的版本适用的hibernate-validator版本号

常用校验注解混个眼熟

注解作用适用类型
@NotNull被注解的元素必须不为nullobject
@NotBlank验证注解的元素值不为空(不为null、去除首位空格后长度为0)String
@Length值长度在min和max区间内String
@Pattern必须符合指定的正则表达式String
@Email是Email格式String
------------
@AssertTrue必须为truebool
@AssertFalse必须是falsebool
------------
@Min其值必须大于等于最小值int,long,float,double
@Max其值必须小于等于最小值int,long,float,double
@DecimalMin其值必须大于等于最小值BigDecimal
@DecimalMax其值必须小于等于最小值BigDecimal
@Range元素值在最小值和最大值之间BigDecimal,BigInteger,CharSequence,byte,short,int,long
@Digits元素值的整数位数和小数位数上限float,double,BigDecimal
------------
@Past元素必须为过去的一个时间java.util.Date
@Future元素必须为未来的一个时间java.util.Date
------------
@Size元素的长度必须在指定范围内Array,List,Map
@NotEmpty元素值不为null且不为空Array,List,Map

错误提示语友好化

需要注意的是,SpringBoot2.3及其以上版本,会自动封装由@Validated 和 @Valid注解校验不通过时的异常,比如如下代码:

@RestController
@RequestMapping("/hello") 
public class HelloController {

    @PostMapping("/requestBodyValid")
    public UserDTO requestBodyValid(@RequestBody @Validated UserDTO userDTO){
        return userDTO;
    }
}


@Data
public class UserDTO {

    @NotNull(message = "id不能为空")
    @Min(value = 1, message = "id最小只能是1")
    private Long id;
}

此时请求接口,结果如下:
在这里插入图片描述
在这里插入图片描述
可见并没有返回校验失败的错误信息,查看应用日志,如下:
在这里插入图片描述
可见Spring对于校验发生的异常进行了封装,这使得前端调用方并不能看到具体的错误信息,十分不友好,所以这里我们使用Spring的统一异常处理机制@RestControllerAdvice 注解来统一对controller返回的异常进行友好化展示

@RestControllerAdvice注解的简单使用

@RestControllerAdvice
public class ExceptionHandler {

    @org.springframework.web.bind.annotation.ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    public ResultVO validExceptionHandle(MethodArgumentNotValidException exception){
        BindingResult bindingResult = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder("校验失败:");
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMsg.append(fieldError.getDefaultMessage()).append(";");
        }
        return new ResultVO()
                .setCode(ResultVO.VALID_NOT_PASS)
                .setMsg(errorMsg.toString())
                ;
    }
}

@Data
@Accessors(chain = true)
public class ResultVO {

    public static final String VALID_NOT_PASS = "40";

    public static final String VALID_PASS = "00";

    private String msg;

    private String code;
}

然后,我们再以相同的入参调用接口,可得到如下的返回值:
在这里插入图片描述
可见这样的提示信息就很友好化了。
下面是其他条件校验注解的简单使用:

@Data
public class UserDTO {

    @NotNull(message = "notNull校验")
    private Object notNull;

    @NotBlank(message = "notBlank校验")
    private String notBlank;

    @Length(min = 1, max = 10, message = "length(1--10)校验")
    private String length;

    @Pattern(regexp = "^\\d{2}$",message = "pattern(正则表达式匹配两位数字)校验")
    private String pattern;

    @Email(message = "email校验")
    private String email;

    @AssertFalse(message = "assertFalse校验")
    private Boolean assertFalse;

    @AssertTrue(message = "assertTrue校验")
    private Boolean assertTrue;


    @Min(value = 1, message = "min值是1-校验")
    private Integer min;

    @Max(value = 10, message = "max值是10-校验")
    private Integer max;

    @DecimalMin(value = "1.1", message = "decimalMin值是1.1-校验")
    private BigDecimal decimalMin;

    @DecimalMax(value = "10.1", message = "decimalMax值是10.1-校验")
    private BigDecimal decimalMax;

    @Range(min = 1, max = 10, message = "range(1--10)-校验")
    private Integer range;

    @Digits(integer = 2, fraction = 2, message = "digits(2,2)-校验")
    private Double digits;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Past(message = "past校验")
    private Date past;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Future(message = "future校验")
    private Date future;

    @Size(min = 1, max = 3, message = "size(1--3)校验")
    private List<Integer> size;

    @NotEmpty(message = "集合不能为null或者空集合")
    private List<Integer> notEmpty;
}

入参:

{
  "notBlank": "",
  "length": "123456789012",
  "pattern": "123",
  "email": "456aasd",
  "assertFalse": true,
  "assertTrue": false,
  "min": 0,
  "max": 11,
  "decimalMin": 1.0,
  "decimalMax": 10.2,
  "range": -1,
  "digits": 99.999,
  "past": "2024-06-25 21:04:18",
  "future": "2022-06-25 21:04:18",
  "size": [
    1,2,3,4
  ],
  "notEmpty": [
    
  ]
}

出参:
在这里插入图片描述
好了,今天就先到这里了,拜拜

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值