简介

@Validation是一套帮助我们继续对传输的参数进行数据校验的注解,通过配置Validation可以很轻松的完成对数据的约束,配合BindingResult可以直接提供参数验证结果

所有参数注解含义


参考
@Validated注解详解,分组校验,嵌套校验,@Valid和@Validated 区别,Spring Boot @Validated

区别

javax.validation.Valid.@Valid

① 首先需要在实体类的相应字段上添加用于充当校验条件的注解,如:@Min,如下代码(age属于Girl类中的属性):

@Min(value = 18,message = "未成年禁止入内")
private Integer age;

② 其次在controller层的方法的要校验的参数上添加@Valid注解,并且需要传入BindingResult对象,用于获取校验失败情况下的反馈信息,如下代码:

@PostMapping("/girls")
public Girl addGirl(@Valid Girl girl, BindingResult bindingResult) {  if(bindingResult.hasErrors()){  System.out.println(bindingResult.getFieldError().getDefaultMessage());  return null;  }  return girlResposity.save(girl);
}

bindingResult.getFieldError.getDefaultMessage()用于获取相应字段上添加的message中的内容,如:@Min注解中message属性的内容

javax.validation.@Validated

@Validated是@Valid 的一次封装,是Spring提供的校验机制使用。@Valid不提供分组功能

分组

当一个实体类需要多种验证方式时,例:对于一个实体类的id来说,新增的时候是不需要的,对于更新时是必须的。 可以通过groups对验证进行分组

package com.valid.pojo;  import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;  import com.valid.interfaces.First;  public class People {  //在First分组时,判断不能为空  @NotEmpty(groups={First.class})  private String id;  //name字段不为空,且长度在3-8之间  @NotEmpty  @Size(min=3,max=8)  private String name;  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public String getId() {  return id;  }  public void setId(String id) {  this.id = id;  }  public interface First {}
}
(1)不分配groups,默认每次都要进行验证(2)对一个参数需要多种验证方式时,也可通过分配不同的组达到目的。例:@NotEmpty(groups={First.class})
@Size(min=3,max=8,groups={Second.class})
private String name;
@Controller
public class FirstController {  @RequestMapping("/addPeople")  //不需验证ID  public @ResponseBody String addPeople(@Validated People p,BindingResult result) {  ...}  @RequestMapping("/updatePeople")  //需要验证ID  public @ResponseBody String updatePeople(@Validated({First.class}) People p,BindingResult result) {  ...}
}

@Validated没有添加groups属性时,默认验证没有分组的验证属性,如该例子:People的name属性。如果所有参数的验证类型都设置了分组(即本例中People的name的@NotEmpty@Size都添加groups属性),则不验证任何参数

注意

controller 接口中使用 @Validated 时@Validated(groups = A.class) 设置了 groups 属性,则只有 配置了 groups = A.class 的效验注解会生效,没有配置的全不生效
@Validated  没有设置 groups 属性,则所有效验注解都会生效

controller中,不使用@Valid注解,而是要使用@Validated,里面value代表的是,在User类里面@NotNull注解里面配置了groups里面有TestNotNull.class的字段判断会生效
那么当前配置的话,就只会判断username是否为空,而password因为没有配置同样的groups属性,所以不会生效

@GetMapping("test")
public Result test(@Validated(value = {TestNotNull.class}) User user) {System.out.println("测试@notNull注解");//验证密码操作省略return Result.suc();
}

这里没有传password,代码没有抛异常,说明@Validated注解不会判断groups属性没有当前class的注解,再试一下不传username会不会抛异常

这里没有传username,返回的是用户名不能为空,说明配置成功了,如果以后开发中,在多个接口中有不同的判断体系,可以用groups的方式分组

验证多个对象

一个功能方法上处理多个模型对象时,需添加多个验证结果对象

@Controller
public class FirstController {  @RequestMapping("/addPeople")  public @ResponseBody String addPeople(@Validated People p,BindingResult result,@Validated Person p2,BindingResult result2) {  ...}
}

总结

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Valid {}
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {Class<?>[] value() default {};
}
@Valid:没有分组的功能。@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上
@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制@Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上
@Validated:用在方法入参上无法单独提供嵌套验证功能。不能用在成员属性(字段)上,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。@Valid:用在方法入参上无法单独提供嵌套验证功能。能够用在成员属性(字段)上,提示验证框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。

嵌套验证

public class Item {@NotNull(message = "id不能为空")@Min(value = 1, message = "id必须为正整数")private Long id;@NotNull(message = "props不能为空")@Size(min = 1, message = "至少要有一个属性")private List<Prop> props;
}

Item带有很多属性,属性Prop里面有属性id,属性值vid,属性名和属性值,如下所示:

public class Prop {@NotNull(message = "pid不能为空")@Min(value = 1, message = "pid必须为正整数")private Long pid;@NotNull(message = "vid不能为空")@Min(value = 1, message = "vid必须为正整数")private Long vid;@NotBlank(message = "pidName不能为空")private String pidName;@NotBlank(message = "vidName不能为空")private String vidName;
}

属性Prop这个实体也有自己的验证机制,比如属性和属性值vid不能为空,属性名和属性值不能为空等。
现在我们有个ItemController接受一个Item的入参,想要对Item进行验证,如下所示:

@RestController
public class ItemController {@RequestMapping("/item/add")public void addItem(@Validated Item item, BindingResult bindingResult) {doSomething();}
}

如果Item实体的props属性不额外加注释只有@NotNull和@Size,无论入参采用@Validated还是@Valid验证,Spring Validation框架只会对Item的id和props做非空和数量验证不会对props字段里的Prop实体进行字段验证

也就是@Validated@Valid加在方法参数前,都不会自动对参数进行嵌套验证

也就是说如果传的List<Prop>中有Prop的pid为空或者是负数,入参验证不会检测出来。

为了能够进行嵌套验证,必须手动Item实体的props字段上 明确指出这个字段里面的实体也要进行验证

所以
request  中的参数 尽量不要是其他的 dto , 可以是 enum ,如果必须用其他 dto,可以作为 静态内部类

由于@Validated不能用在成员属性(字段)上,但是@Valid能加在成员属性(字段)上,而且@Valid类注解上也说明了它支持嵌套验证功能

那么我们能够推断出:

@Valid加在方法参数时并不能够自动进行嵌套验证
而是用在需要嵌套验证类的相应字段上,来配合方法参数上@Validated或@Valid来进行嵌套验证
public class Item {@NotNull(message = "id不能为空")@Min(value = 1, message = "id必须为正整数")private Long id;@Valid // 嵌套验证必须用@Valid@NotNull(message = "props不能为空")@Size(min = 1, message = "props至少要有一个自定义属性")private List<Prop> props;
}

然后我们在ItemControlleraddItem函数上再使用@Validated或者@Valid,就能对Item的入参进行嵌套验证。此时Item里面的props如果含有Prop的相应字段为空的情况,Spring Validation框架就会检测出来bindingResult就会记录相应的错误

好的实现方式

List<包装类>包装类的效验

@Data
@ApiModel
public class xxx {@ApiModelProperty("xxx")@Size(max = 100)@NotEmptyprivate List<@NotBlank String> xxx;
}

自定义封装全局异常类

package com.example.apps.advice;import com.example.apps.result.ServiceResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;@RestControllerAdvice
public class GlobalControllerAdvice {@ExceptionHandler(value = ConstraintViolationException.class)public ServiceResult errorHandler(ConstraintViolationException ex) {ServiceResult serviceResult = new ServiceResult(400);Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();if (!CollectionUtils.isEmpty(constraintViolations)) {StringBuilder stringBuilder = new StringBuilder();for (ConstraintViolation constraintViolation : constraintViolations) {stringBuilder.append(constraintViolation.getMessage()).append(",");}String errorMessage = stringBuilder.toString();if (errorMessage.length() > 1) {errorMessage = StringUtils.removeEnd(errorMessage, ",");serviceResult.setMessage(errorMessage);return serviceResult;}}serviceResult.setMessage(ex.getMessage());return serviceResult;}@ExceptionHandler(value = MethodArgumentNotValidException.class)public ServiceResult errorHandler(MethodArgumentNotValidException ex) {ServiceResult serviceResult = new ServiceResult(400);List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();if(!CollectionUtils.isEmpty(objectErrors)) {StringBuilder builder = new StringBuilder();for (ObjectError objectError : objectErrors) {builder.append(objectError.getDefaultMessage()).append(",");}String errorMessage = builder.toString();if (errorMessage.length() > 1) {errorMessage = StringUtils.removeEnd(errorMessage,",");}serviceResult.setMessage(errorMessage);return serviceResult;}serviceResult.setMessage(ex.getMessage());return serviceResult;}
}

对Controller里的方法的多个参数进行校验

Controller里的方法的多个参数进行校验(扁平化参数):在Controller类上加注解@Validated

@RestController
@RequestMapping
@Validated
public class HelloController {@PutMapping("/hello/id/{id}/status/{status}")public Object helloGet(@Max(5) @PathVariable Integer id, @Min(5) @PathVariable Integer status) {return "hello world";}
}

@Valid和@Validated相关推荐

  1. 校验注解:@Valid 和 @Validated区别与用法(附详细案例)

    一.案例对象 本文章会以案例为主,讲解@Valid 和 @Validated这两个注解的区别与用法. 1.首先,创建一个学生对象,如下: import lombok.Data;/*** 学生对象*/ ...

  2. @Valid和@Validated注解校验List<Object>

    @Valid和@Validated注解校验List< Object> spring 4整合hibernate-validator6 1.导包 <dependency><g ...

  3. Java校验框架使用@Valid、@Validated、OVAL+Groovy

    @Valid 与 @Validated Spring Validation验证框架对参数的验证机制提供了@Validated; javax提供了@Valid,配合BindingResult可以直接提供 ...

  4. 常用校验注解@NotEmpty,@NotBlank,@NotNull,@Valid,@Validated用法区别,以及搭配 BindingResult使用,嵌套验证等《使用|CSDN创作打卡》

    文章目录 一.常用注解@NotEmpty,@NotBlank,@NotNull介绍 二.@Valid与@Validated的使用与区别 2.1@Valid与@Validated区别: 2.2嵌套验证 ...

  5. @Valid和@Validated验证List集合--网络踩坑记录

    基于Springboot框架验证list只需要一下两步: 在Controller上添加@Validated注解,方法上添加@Valid注解,就能验证了 实体类: 情况二.只是用@Valid,并且不是S ...

  6. 一文探知@Valid和@Validated 的区别

    使用spring boot开发的道友们,或许或多或少有用到过这两个注解,那么今天我们就来探查一下这两者的异同. 两者都可以使开发人员写的注解校验规则生效,例如在某一个字段上加上@NotNull.@No ...

  7. Spring中@NotEmpty,@NotBlank,@NotNull,@Valid,@Validated注解简介及简单使用

    前言 在开发中,为了代码的稳定性不报空指针异常,经常需要判断前端传过来的值是否为空,为空的话就返回前端值为空的提示,才能进行下一步的操作 Maven依赖的引入: springboot 2.3.0 以后 ...

  8. @Validated注解详解,分组校验,嵌套校验,@Valid和@Validated 区别,Spring Boot @Validated

    技术栈: spring boot 2.3.3.RELEASE hibernate-validator 文末附项目源代码 目录 简述 项目依赖 全局异常处理类 基础参数校验 实体类 控制类 测试 嵌套参 ...

  9. @Valid与@Validated区别

    1.@Valid与@Validated作用 @Valid与@Validated都是用来校验接收参数的.@Valid是使用Hibernate validation的时候使用@Validated是只用Sp ...

最新文章

  1. java对象序列化克隆_JAVA 对象克隆和序列化
  2. java 扩展类加载器_java实现自定义类加载器
  3. 对码农的忠告---内心不强大者绕道勿看-来自某CTO的演讲
  4. C++ :学习(类、指针)
  5. linux安装python3.6_Linux环境下安装python3.6
  6. 十、Hadoop学习笔记————Hive与Hbase以及RDBMS(关系型数据库)的关系
  7. 20145319 第五周学习总结
  8. NoPause/NoEmgAbort的任务 与后台任务的区别
  9. WebDriver API元素的定位
  10. fast rcnn 论文解读(附代码链接)
  11. 何以笙箫默,一部有剧情的创意广告集?
  12. 3D引擎多线程:资源异步加载
  13. python能做什么-学会Python后都能做什么?网友们的回答简直不要太厉害
  14. 获取窗口句柄 c语言,VC++编程获取窗口句柄的方法小结分享
  15. LDA模型原理学习及应用
  16. Springboot企业出纳系统的设计与实现7k9je计算机毕业设计-课程设计-期末作业-毕设程序代做
  17. 少数派实测报告:AI巨无霸模型GPT-3 | 附送API 调用方法「AI核心算法」
  18. selinux-001
  19. JavaScript:一个非常有趣的猜数小游戏
  20. uniapp 简陋易懂版仿抖音视频播放

热门文章

  1. 心中有佛,看人如佛;心中有魔,看人如魔。
  2. 用c语言输出一个字母的,用c语言编写程序输出一个短句
  3. springboot多模块工程单元测试jacoco统计代码覆盖率总结
  4. websocket连接及心跳检测
  5. 默认字间距html,HTML连载42-清空默认边距、文字行高,字间距分享
  6. opencv设置摄像头获取图片大小
  7. es备份数据和恢复数据
  8. Comparable类
  9. ESET中自带的白利用
  10. 纽蒙特宣布附条件特别股息