Springboot参数校验@Validated和@Valid区别

您所在的位置:网站首页 onsale和onsales的区别如题 Springboot参数校验@Validated和@Valid区别

Springboot参数校验@Validated和@Valid区别

2024-07-15 02:14| 来源: 网络整理| 查看: 265

@Validated和@Valid区别

上一篇讲了springboot自定义参数校验规则,本篇我们讲解@Validated和@Valid区别。Springboot中参数的校验我们可以使用@Validated和@Valid两个注解,这两个注解有什么区别?那种情况下使用@Validated注解?那种情况下使用@Valid注解?

带着这几个疑问我们先看看这两个注解的源码:

Validated源码如下:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Validated { Class[] value() default {}; }

@Valid源码如下:

@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) public @interface Valid { }

Java中@Target注解的作用目标如下:

注解描述ElementType.TYPE接口、类、枚举ElementType.FIELD字段、枚举的常量ElementType.METHOD方法ElementType.PARAMETER方法参数ElementType.CONSTRUCTOR构造函数ElementType.LOCAL_VARIABLE局部变量ElementType.ANNOTATION_TYPE注解ElementType.PACKAGE包

通过查看@Target属性,可知:

Valid可以用在:方法,字段、枚举的常量,构造函数,方法参数

Validated可以用在:接口、类、枚举、注解,方法,方法参数

通过上面的对比我们可以看出valid 可以作用在 字段、枚举的常量 上面,而Validated 不可以,所以嵌套校验需要使用 Valid。Validated 多了一个参数用于分组校验,所以如果需要分组校验需要使用Validated。

综上所诉,两者的区别如下:

@Valid:标准JSR-303规范的标记型注解,用来标记验证属性和方法返回值,进行级联和递归校验@Validated:Spring的注解,是标准JSR-303的一个变种(补充),提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制

Valid嵌套校验使用方式

比如我们定义了一个PeopleDTO,该DTO下的地址信息是一个对象,我们对地址信息也需要进行校验,校验方式如下:

我们在AddressDTO上面加上了 @Valid注解就可以实现嵌套校验了

package com.validator.demo.api.model.dto; import java.io.Serializable; import javax.validation.Valid; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.NotBlank; public class PeopleDTO implements Serializable { private static final long serialVersionUID = 7515422823626784776L; @NotBlank(message = "姓名不能为空") private String name; @NotBlank(message = "性别不能为空") private String sex; @NotBlank(message = "生日不能为空") @Pattern(regexp = "[0-9]{4}-[0-9]{2}-[0-9]{2}", message = "生日输入数据异常,请确认!") private String birthday; @Valid private AddressDTO address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public AddressDTO getAddress() { return address; } public void setAddress(AddressDTO address) { this.address = address; } public static long getSerialversionuid() { return serialVersionUID; } }

AddressDTO源码如下:

package com.validator.demo.api.model.dto; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotBlank; public class AddressDTO { @NotBlank(message = "地址不能为空!") @Size(min = 6, message = "地址不能小于六个字符,请确认!") private String addr; @NotBlank(message = "邮箱不能为空!") private String email; public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }

Controller类的代码如下:

package com.validator.demo.api.controller; import javax.validation.Valid; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.validator.demo.api.base.DateResult; import com.validator.demo.api.model.dto.PeopleDTO; import com.validator.demo.api.model.vo.PeopleVO; @RestController @RequestMapping("/test/api") public class ValidatorController { @PostMapping("/validatortest") public DateResult test(@RequestBody @Valid PeopleDTO peopleDTO) { DateResult dateResult = new DateResult(); //具体的业务逻辑 //省略 return dateResult; } }

PostMan运行测试结果如下:

Validated 分组校验使用方式

在实际项目中,可能多个方法需要使用同一个DTO类来接收参数,而不同方法的校验规则很可能是不一样的。这个时候,简单地在DTO类的字段上加约束注解无法解决这个问题。比如PeopleDTO中新增的时候姓名不可以为空,修改的时候性别不可以为空,生日新增和修改都不可以为空。分组校验实现方式如下:

我们先定义两个分组类,一个是AddGroup,一个是UpdateGroup,源码如下:

package com.validator.demo.api.validation; public abstract interface AddGroup { } package com.validator.demo.api.validation; public abstract interface UpdateGroup { }

PeopleDTO代码如下:

package com.validator.demo.api.model.dto; import java.io.Serializable; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.NotBlank; import com.validator.demo.api.validation.AddGroup; import com.validator.demo.api.validation.UpdateGroup; public class PeopleDTO implements Serializable { private static final long serialVersionUID = 7515422823626784776L; @NotBlank(groups = { AddGroup.class }, message = "姓名不能为空") private String name; @NotBlank(groups = { UpdateGroup.class }, message = "性别不能为空") private String sex; @NotNull(groups = { AddGroup.class, UpdateGroup.class }, message = "生日不能为空") @Pattern(regexp = "[0-9]{4}-[0-9]{2}-[0-9]{2}", message = "生日输入数据异常,请确认!") private String birthday; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public static long getSerialversionuid() { return serialVersionUID; } }

在Controller中我们定义两个方法,一个是新增,一个是修改。在参数的前面添加@Validated注解,并添加相应的分组,代码如下:

package com.validator.demo.api.controller; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.validator.demo.api.base.DateResult; import com.validator.demo.api.model.dto.PeopleDTO; import com.validator.demo.api.model.vo.PeopleVO; import com.validator.demo.api.validation.AddGroup; import com.validator.demo.api.validation.UpdateGroup; @RestController @RequestMapping("/test/api") public class ValidatorController { @PostMapping("/validatoradd") public DateResult add(@RequestBody @Validated(AddGroup.class) PeopleDTO peopleDTO) { DateResult dateResult = new DateResult(); //具体的业务逻辑 //省略 return dateResult; } @PostMapping("/validatorupdate") public DateResult update(@RequestBody @Validated(UpdateGroup.class) PeopleDTO peopleDTO) { DateResult dateResult = new DateResult(); //具体的业务逻辑 //省略 return dateResult; } }

使用postman调用验证一下校验。我们的逻辑为新增的时候姓名不可以为空,修改的时候性别不可以为空,生日新增和修改都不可以为空。我们先调用新增方法,不传递姓名,返回结果如下:

然后调用修改方法,不传递性别,返回结果如下:

​测试源码,点击链接下载



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3