Springboot @Validated和@Valid的区别及使用详解

概述:

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

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

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

@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明。

注解位置:

@Validated:用在类型、方法和方法参数上。但不能用于成员属性(field)

@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上

如:

   ==================》》》》       

如果@Validated注解在成员属性上,则会报  不适用于field错误

分组校验:

@Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制

@Valid:没有分组功能

举例:

定义分组接口:

public interface IGroupA {
}

public interface IGroupB {
}

定义需要检验的参数bean:

public class StudentBean implements Serializable{
  @NotBlank(message = "用户名不能为空")
  private String name;
  //只在分组为IGroupB的情况下进行验证
  @Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupB.class})
  private Integer age;
  @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
  private String phoneNum;
  @Email(message = "邮箱格式错误")
  private String email;
  @MyConstraint
  private String className;

测试代码:

检验分组为IGroupA的情况

@RestController
public class CheckController {
  @PostMapping("stu")
  public String addStu(@Validated({IGroupA.class}) @RequestBody StudentBean studentBean){
    return "add student success";
  }
}

测试:

这里对分组IGroupB的就没检验了

如果把测试代码改成下面这样,看看测试结果

@RestController
public class CheckController {
  @PostMapping("stu")
  public String addStu(@Validated({IGroupA.class, IGroupB.class}) @RequestBody StudentBean studentBean){
    return "add student success";
  }
}

说明:

1、不分 配groups,默认每次都要进行验证

2、对一个参数需要多种验证方式时,也可通过分配不同的组达到目的。

组序列:

默认情况下 不同级别的约束验证是无序的,但是在一些情况下,顺序验证却是很重要。

一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。

举例:

定义组序列:

@GroupSequence({Default.class, IGroupA.class, IGroupB.class})
public interface IGroup {
}

需要校验的Bean,分别定义IGroupA对age进行校验,IGroupB对className进行校验:

public class StudentBean implements Serializable{
  @NotBlank(message = "用户名不能为空")
  private String name;
  @Min(value = 18, message = "年龄不能小于18岁", groups = IGroupA.class)
  private Integer age;
  @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
  private String phoneNum;
  @Email(message = "邮箱格式错误")
  private String email;
  @MyConstraint(groups = IGroupB.class)
  private String className

测试代码:

@RestController
public class CheckController {
  @PostMapping("stu")
  public String addStu(@Validated({IGroup.class}) @RequestBody StudentBean studentBean){
    return "add student success";
  }
}

测试发现,如果age出错,那么对组序列在IGroupA后的IGroupB不进行校验,即例子中的className不进行校验,结果如下:

嵌套校验:

一个待验证的pojo类,其中还包含了待验证的对象,需要在待验证对象上注解@Valid,才能验证待验证对象中的成员属性,这里不能使用@Validated。

举例:

需要约束校验的bean:

public class TeacherBean {
  @NotEmpty(message = "老师姓名不能为空")
  private String teacherName;
  @Min(value = 1, message = "学科类型从1开始计算")
  private int type;
public class StudentBean implements Serializable{
  @NotBlank(message = "用户名不能为空")
  private String name;
  @Min(value = 18, message = "年龄不能小于18岁")
  private Integer age;
  @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
  private String phoneNum;
  @Email(message = "邮箱格式错误")
  private String email;
  @MyConstraint
  private String className;

  @NotNull(message = "任课老师不能为空")
  @Size(min = 1, message = "至少有一个老师")
  private List<TeacherBean> teacherBeans;

注意:

这里对teacherBeans只校验了NotNull, 和 Size,并没有对teacher信息里面的字段进行校验,具体测试如下:

这里teacher中的type明显是不符合约束要求的,但是能检测通过,是因为在student中并没有做 嵌套校验

可以在teacherBeans中加上 @Valid,具体如下:

 @Valid
  @NotNull(message = "任课老师不能为空")
  @Size(min = 1, message = "至少有一个老师")
  private List<TeacherBean> teacherBeans;

这里再来测试,会发现如下结果:

到此这篇关于Springboot @Validated和@Valid的区别及使用详解的文章就介绍到这了,更多相关Springboot @Validated和@Valid内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring Boot 数据校验@Valid+统一异常处理的实现

    1.先在你需要校验的实体类上面加上所需要的注解 为了测试,我自己就简单写了.@NotNull 和 @NotBlank 不能为空 @Entity @Table(name = "User") @Data public class User implements Serializable { @Id @NotNull(message = "id不能为空") @GeneratedValue(strategy = GenerationType.IDENTITY) privat

  • Springboot使用@Valid 和AOP做参数校验及日志输出问题

    项目背景 最近在项目上对接前端的的时候遇到了几个问题 1.经常要问前端要请求参数 2.要根据请求参数写大量if...else,代码散步在 Controller 中,影响代码质量 3.为了解决问题1,到处记日志,导致到处改代码 解决方案 为了解决这类问题,我使用了@Valid 做参数校验,并使用AOP记录前端请求日志 1.Bean实体类增加注解 对要校验的实体类增加注解,如果实体类中有List结构,就在List上加@Valid @Valid注解 注解 备注 @Null 只能为null @NotNu

  • springboot @Valid注解对嵌套类型的校验功能

    @Valid注解可以实现数据的验证,你可以定义实体,在实体的属性上添加校验规则,而在API接收数据时添加@valid关键字,这时你的实体将会开启一个校验的功能,具体的代码如下,是最基本的应用: 实体: public class DepartmentDto { @ApiModelProperty("id") private String id; @ApiModelProperty("上级Id") private String parentId; @ApiModelPr

  • Springboot @Validated和@Valid的区别及使用详解

    概述: @Valid是使用Hibernate validation的时候使用 @Validated是只用Spring Validator校验机制使用 说明:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现 @Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组.注解位置.嵌套验证等功能上有所不同,这里主要就这几种情况进行说明. 注解位置: @Validated:用在类型.方法和方法参数上.但不能用于成员属性(fie

  • springboot @Controller和@RestController的区别及应用详解

    目录 @Controller和@RestController的区别及应用 @Controller和@RestController区别 @Controller的应用 @RestController的应用 @Controller和@RestController区别的小坑 1.如果注解Controller使用@RestController 2.如果需要返回到指定页面(jsp/html) @Controller和@RestController的区别及应用 @Controller和@RestControl

  • SpringBoot中注解@ConfigurationProperties与@Value的区别与使用详解

    目录 注解@ConfigurationProperties 注解@Value 区别 松散语法绑定: SpEl语法表示: JSR303数据校验: 复杂类型封装: 配置文件注入值数据校验 注解@ConfigurationProperties 该注解的作用是将配置文件中配置的每一个属性的值,映射到这个组件中.@ConfigurationProperties :告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定 prefix = "person":配置文件中哪个下面的所有

  • SpringBoot后端进行数据校验JSR303的使用详解

    如果只想查看注解,请跳到文章末尾部分 简介 在前后端进行数据交互中,在前端把数据传送到后端前,一般会先进行校验一次,校验成功之后,才把数据发送到后端.但是我们在服务端还得在对数据进行一次校验.因为请求数据发送的链接很容易获取,可以不经过前端界面,使用postman等工具直接向后台发送数据,这就可能造成发送的数据是不合法的情况. 项目创建 首先创建一个springboot项目 使用的springboot版本为:(本文代码以该版本为准,不同版本springboot,在下面内容会出现一些差异) <pa

  • SpringBoot集成mqtt的多模块项目配置详解

    前言 近期为了准备毕设,准备使用SpringBoot搭建mqtt后端,本篇主要记录了在IDEA中搭建SpringBoot mqtt的多模块项目的过程 开发工具及系统环境 IDE:IntelliJ IDEA 2020.2 操作系统:Windows 10 2004 Java Version:1.8 SpringBoot Version:2.1.17.RELEASE 项目路径 Study |----study-common # 存放公共类 |----study-mapper # mapper层 |--

  • SpringBoot文件上传与下载功能实现详解

    目录 前言 1.引入Apache Commons FileUpload组件依赖 2.设置上传文件大小限制 3.创建选择文件视图页面 4.创建控制器 5.创建文件下载视图页面 前言 文件上传与下载是Web应用开发中常用的功能之一,在实际的Web应用开发中,为了成功上传文件,必须将表单的method设置为post,并将enctype设置为multipart/form-data 只有这样设置,浏览器才能将所选文件的二进制数据发送给服务器 从Servlet3.0开始,就提供了处理文件上传的方法,但这种文

  • Springboot Vue可配置调度任务实现示例详解

    目录 正文 1.表结构: 2.接口: 3.业务层: 4.Mapper 5.前端(Vue): 正文 Springboot + Vue,定时任务调度的全套实现方案. 这里用了quartz这个框架,实现分布式调度任务很不错,关于quarz的使用方式改天补一篇.相当简单. 1.表结构: sys_job 列名 数据类型 长度 是否可空 是否主键 说明 job_id bigint 否 是 任务ID job_name varchar 64 否 是 任务名称 job_group varchar 64 否 是 任

  • springboot扫描自定义的servlet和filter代码详解

    这几天使用spring boot编写公司一个应用,在编写了一个filter,用于指定编码的filter,如下: /** * Created by xiaxuan on 16/11/1. */ @WebFilter(urlPatterns = "/*",filterName="CharacterEncodeFilter", initParams={ @WebInitParam(name="encoding",value="UTF-8&qu

  • PHP中加速、缓存扩展的区别和作用详解(eAccelerator、memcached、xcache、APC )

    PHP中有eAccelerator.memcached.xcache.APC 4个加速.缓存扩展,下面给大家介绍下其区别,一起看看吧! 折腾VPS的朋友,在安装好LNMP等Web运行环境后都会选择一些缓存扩展安装以提高PHP运行速度,常被人介绍的有 eAccelerator.memcached.xcache.Alternative PHP Cache这几个缓存扩展,它们之间有什么区别?分别的作用又是什么?我们如何选择?这是本文给于大家的答案. 1.eAccelerator eAccelerato

  • jQuery Ajax的readyState和status的区别和使用详解

    在前几篇分析了jquery的ajax异步和同步,以及异常的一些处理,感觉还没有把ajax的readyState和status说清楚.今天就来说说ajax状态的那点事. jquery ajax函数源代码是这样的: var getXmlHttpRequest = function () { if (window.XMLHttpRequest) { //主流浏览器提供了XMLHttpRequest对象 return new XMLHttpRequest(); } else if (window.Act

随机推荐