@Valid与@Validated区别

1.@Valid与@Validated作用

@Valid与@Validated都是用来校验接收参数的。

@Valid是使用Hibernate validation的时候使用

@Validated是只用Spring Validator校验机制使用

说明:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现。



@Validated与@Valid区别:

@Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,不支持嵌套检测
@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测\



注意:SpringBoot使用@Valid注解需要引入如下POM

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2.为什么要用@Valid或@Validated

@Valid与@Validated都是用来校验接收参数的,如果不使用注解校验参数,那么就需要在业务代码中校验,这
样会增加很多的工作量并且代码不优美。
@RestController
@RequestMapping("/valid")
public class ValidControllerTest {

    public static final Logger logger = LoggerFactory.getLogger(ValidControllerTest.class.getName());

    @PostMapping("/login")
    public String doLogin(@RequestBody LoginUser loginUser){
        if(StringUtils.isEmpty(loginUser.getPhone())){
          //抛出异常
          logger.error("伪代码抛出异常---可以用全局异常捕获");
        }
        if(StringUtils.isEmpty(loginUser.getPassWord())){
          //抛出异常
         logger.error("伪代码抛出异常---可以用全局异常捕获");
        }
        return "数据校验通过";
    }
}

如果需要判断多个参数,那就需要写多个if判断,这样会增加编码工作量并且这样写的不优美。

3.使用@Valid或@Validated来做一个简单的案例

如果@Valid|Validated校验不通过,那么错误信息就会封装到BindingResult对象了,可以通过
BindingResult的相关方法获取详细的错误信息并返回给用户。 代码如下:


public class LoginUser {

    @NotBlank(message = "手机号码不能为空")
    private String phone;

    @NotBlank(message = "密码不能为空")
    private String passWord;
}


@RestController
@RequestMapping("/valid")
public class ValidControllerTest {

    public static final Logger logger = LoggerFactory.getLogger(ValidControllerTest.class.getName());

    @PostMapping("/login")
    public String doLogin(@RequestBody @Validated LoginUser loginUser, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
        }
        return "数据校验通过";
    }
}


loginUser======密码不能为空
loginUser======手机号码不能为空

4.使用@Valid实现嵌套检测

什么是嵌套检测?

嵌套检测就是在一个beanA中,存在另外一个beanB属性。嵌套检测beanA同时也检测beanB。


public class AgeBean {

    @NotNull(message = "年龄不能为空")
    @Max(value = 120,message = "年龄不能超过120岁")
    @Min(value = 0,message = "年龄不能为负数")
    private int age;
}


public class LoginUser {

    @NotBlank(message = "手机号码不能为空")
    private String phone;
    @NotBlank(message = "密码不能为空")
    private String passWord;
    @NotNull(message = "ageBean不能为null")
    private AgeBean ageBean;
}

注意:LoginUser中ageBean属性没有添加@Valid注解,所以只能检测ageBean属性不为空,但是不能
检测AgeBean对象中age属性定义的最大值和最小值。(@Validated不能添加属性上面,不支持嵌套检测所以
只有使用@Valid)


@RequestMapping("/valid")
public class ValidControllerTest {

    public static final Logger logger = LoggerFactory.getLogger(ValidControllerTest.class.getName());

    @PostMapping("/login")
    public String doLogin(@RequestBody @Validated LoginUser loginUser, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
        }
        return "数据校验通过";
    }
}


模拟入参:

{
    "phone":"111",
    "passWord":"",
    "ageBean":{
        "age":-1
    }
}

只抛出密码不为空,没有嵌套检测ageBean属性中的age属性最大值最小值。
loginUser======密码不能为空



添加上@Valid注解,重新测试
public class LoginUser {

    @NotBlank(message = "手机号码不能为空")
    private String phone;
    @NotBlank(message = "密码不能为空")
    private String passWord;
    
    @Valid
    @NotNull(message = "ageBean不能为null")
    private AgeBean ageBean;
}

模拟参数:

{
    "phone":"111",
    "passWord":"",
    "ageBean":{
        "age":-1
    }
}

添加@Valid注解便可以嵌套检测ageBean属性中的age属性的最大值|最小值

loginUser======年龄不能为负数
loginUser======密码不能为空

 5.常用注解说明

@AssertFalse:

所注解的元素必须是Boolean类型,并且值为false

@AssertTrue:

所注解的元素必须是Boolean类型,并且值为true

@DecimalMax:

所注解的元素必须是数字,并且值要小于或等于给定的BigDecimalString值

@DecimalMin:

所注解的元素必须是数字,并且值要小于或等于给定的BigDecimalString值

@Digits:

所注解的元素必须是数字,并且它的值必须有指定的位数

@Email:

所注解的元素要匹配指定的正则表达式

@Max:

所注解的元素必须是数字,并且值要小于或等于给定的值。注意如果@Max所注解的元素是null,则@Max注解
会返回true,所以应该把@Max注解和@NotNull注解结合使用

@Min:

所注解的元素必须是数字,并且值要大于或等于给定的值。注意如果@Min所注解的元素是null,则@Min注解
会返回true,即也会通过校验,所以应该把@Min注解和@NotNull注解结合使用。

@NotBlank:

所注解的元素不能为null且不能为空白,用于校验CharSequence(含String、StringBuilder和StringBuffer)

@NotEmpty:

所注解的元素不能为null且长度大于0,可以是空白,用于校验CharSequence、数组、Collection和Map

@NotNull:

所注解的元素不能为null

@Null:

所注解的元素必须为null

@Pattern:

所注解的元素必须匹配指定的正则表达式。注意如果@Pattern所注解的元素是null,则@Pattern注解会返回
true,即也会通过校验,所以应该把@Pattern注解和@NotNull注解结合使用

@Size:

所注解的元素必须符合指定的大小,该注解可用于数组,CharSequence(含String、StringBuilder和
StringBuffer),Collection和Map。注意如果@Size所注解的元素是null,则@Size注解会返回true,即也
会通过校验,所以应该把@Size注解和@NotNull注解结合使用

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值