Hibernate-Validator 接口参数校验 | 嵌套参数校验
创始人
2024-04-07 12:50:42

      • 0. 依赖:
      • 1. 常用注解:
        • 2. 全局异常处理:
      • 3. 使用场景:
        • 3.1. 接口参数列表校验:
        • 3.2. 实体类参数校验:
          • 3.2.1. 不包含嵌套属性的实体类参数校验:
          • 3.2.2. 包含嵌套属性的实体类参数校验:
          • 3.2.3. 包含嵌套属性集合的实体类参数校验:
          • 3.2.4. 接口参数列表为实体类集合参数校验:
        • 3.3. 非实体类集合参数校验:
        • 3.4. 分组校验:

0. 依赖:

主要是hibernate-validator依赖,可以直接引入,也可以引入spring-boot-starter-validation


org.springframework.bootspring-boot-starter-validation

1. 常用注解:

来源https://blog.csdn.net/ye___li/article/details/107512099

2. 全局异常处理:

  • MethodArgumentNotValidException:入参为实体类,参数校验失败抛出的异常
  • ConstraintViolationException:入参不是实体类,参数校验失败抛出的异常
  • NotReadablePropertyException:入参为实体类集合,参数校验失败抛出的异常

@RestControllerAdvice
public class CommonExceptionHandler {/*** 入参为实体类,参数校验失败抛出的异常MethodArgumentNotValidException拦截** @param ex* @return*/@ExceptionHandler({MethodArgumentNotValidException.class})@ResponseStatus(HttpStatus.OK)@ResponseBodypublic BaseResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {BindingResult bindingResult = ex.getBindingResult();StringBuilder sb = new StringBuilder("校验失败:");for (FieldError fieldError : bindingResult.getFieldErrors()) {sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");}String msg = sb.toString();return BaseResponse.FAILURE(msg);}/*** 入参不是实体类,参数校验失败抛出的异常ConstraintViolationException拦截** @param ex* @return*/@ExceptionHandler({ConstraintViolationException.class})@ResponseStatus(HttpStatus.OK)@ResponseBodypublic BaseResponse handleConstraintViolationException(ConstraintViolationException ex) {return BaseResponse.FAILURE(ex.getMessage());}/*** 入参为实体类集合,参数校验失败抛出的异常NotReadablePropertyException拦截,但无法获取哪个字段参数校验失败** @param ex* @return*/@ExceptionHandler({NotReadablePropertyException.class})@ResponseStatus(HttpStatus.OK)@ResponseBodypublic BaseResponse handleNotReadablePropertyException(NotReadablePropertyException ex) {return BaseResponse.FAILURE(ex.getMessage());}
}

3. 使用场景:

3.1. 接口参数列表校验:

根据不同场景,使用上文1小节提到的常用注解进行校验,比如@NotNull

  • 【举个栗子】:入参account不能为null,长度必须在【6,20】之间

在这里插入图片描述

3.2. 实体类参数校验:

【实体类】:


@Data
public class UserDTO {@NotNullprivate Long userId;@Length(min = 2, max = 10)private String userName;@Validprivate Job job;@Valid@NotEmptyprivate List banks;@Datapublic static class Job {@NotNullprivate Long jobId;@Length(min = 2, max = 10)private String jobName;}@Datapublic static class Bank {@Length(min = 2, max = 10)private String bankName;@NotNull@Length(min = 2, max = 10)private String position;}
}

【接口方法】:

    @PostMapping("/save")public BaseResponse saveUser(@RequestBody @Validated UserDTO userDTO) {// 校验通过,才会执行业务逻辑处理return BaseResponse.SUCCESS();}
3.2.1. 不包含嵌套属性的实体类参数校验:

实体类的字段加上注解,接口方法中加上 @Validated 注解即可

在这里插入图片描述

3.2.2. 包含嵌套属性的实体类参数校验:
  • 往往实体类里面还包含则其它实体类,这时再嵌套的实体类加上@Valid即可
  • 嵌套的实体类正常使用注解校验,当然接口方法要加上 @Validated 注解
  • 不同场景,允许嵌套实体类为空,只要不标注@NotNull即可;实体类内添加校验注解,只要嵌套实体类不为空,就会校验

在这里插入图片描述

在这里插入图片描述

3.2.3. 包含嵌套属性集合的实体类参数校验:
  • 往往实体类里面还包含则其它实体类集合,这时再嵌套的实体类加上@Valid即可
  • 嵌套的实体类正常使用注解校验,当然接口方法要加上 @Validated 注解

在这里插入图片描述
在这里插入图片描述

3.2.4. 接口参数列表为实体类集合参数校验:
  • 参数列表下使用List去接,即便实体类添加了参数校验注解,但是不会生效
  • 需要自定义一个list集合来接收参数,并使用@Delegate注解(可以不用手动重写父类方法)
  • 校验失败会抛出NotReadablePropertyException异常,如果全局异常拦截,,却无法获取哪个字段参数校验失败;栗子没有拦截
public class ValidationList implements List {@Delegate // @Delegate是lombok注解 ,1.18.6以上版本可支持@Valid // 一定要加@Valid注解public List list = new ArrayList<>();// 一定要记得重写toString方法@Overridepublic String toString() {return list.toString();}
}

在这里插入图片描述

3.3. 非实体类集合参数校验:

在这里插入图片描述
在这里插入图片描述

3.4. 分组校验:

  • 不同场景共用同一个实体类,而且校验规则不一样,这时可以使用分组校验
  • 使用时,在对于的注解加上group即可,值为定义的类或接口都可以,如 @NotNull(groups = {Update.class})
  • 接口参数列表使用的@Validated(UserDTO1.Save.class) ,也要标注用的哪个分组规则

【实体类】:


@Data
public class UserDTO1 {@NotNull(groups = {Update.class})private Long userId;@Length(min = 2, max = 10, groups = {Save.class})private String userName;@Validprivate Job job;@Datapublic static class Job {@NotNull(groups = {Update.class})private Long jobId;@Length(min = 2, max = 10, groups = {Save.class})private String jobName;}/*** 保存的时候校验分组*/public interface Save {}/*** 更新的时候校验分组*/public interface Update {}
}

【举个栗子】:添加时userId允许为空,更新时不允许为空

在这里插入图片描述

在这里插入图片描述

原理和更多内容可以查看参考链接二

【参考链接】:
·
 参考一:Hibernate Validator 参数验证 单个实体类与List集合的验证
 参考二:SpringBoot 实现接口的各种参数校验

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...