Hibernate-Validator 接口参数校验 | 嵌套参数校验
Posted 做猪呢,最重要的是开森啦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate-Validator 接口参数校验 | 嵌套参数校验相关的知识,希望对你有一定的参考价值。
0. 依赖:
主要是hibernate-validator依赖,可以直接引入,也可以引入spring-boot-starter-validation
<!--里面间接引入hibernate-validator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
1. 常用注解:
2. 全局异常处理:
- MethodArgumentNotValidException:入参为实体类,参数校验失败抛出的异常
- ConstraintViolationException:入参不是实体类,参数校验失败抛出的异常
- NotReadablePropertyException:入参为实体类集合,参数校验失败抛出的异常
@RestControllerAdvice
public class CommonExceptionHandler
/**
* 入参为实体类,参数校验失败抛出的异常MethodArgumentNotValidException拦截
*
* @param ex
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public 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)
@ResponseBody
public BaseResponse handleConstraintViolationException(ConstraintViolationException ex)
return BaseResponse.FAILURE(ex.getMessage());
/**
* 入参为实体类集合,参数校验失败抛出的异常NotReadablePropertyException拦截,但无法获取哪个字段参数校验失败
*
* @param ex
* @return
*/
@ExceptionHandler(NotReadablePropertyException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public BaseResponse handleNotReadablePropertyException(NotReadablePropertyException ex)
return BaseResponse.FAILURE(ex.getMessage());
3. 使用场景:
3.1. 接口参数列表校验:
根据不同场景,使用上文1小节提到的常用注解进行校验,比如@NotNull
- 【举个栗子】:入参account不能为null,长度必须在【6,20】之间
3.2. 实体类参数校验:
【实体类】:
@Data
public class UserDTO
@NotNull
private Long userId;
@Length(min = 2, max = 10)
private String userName;
@Valid
private Job job;
@Valid
@NotEmpty
private List<Bank> banks;
@Data
public static class Job
@NotNull
private Long jobId;
@Length(min = 2, max = 10)
private String jobName;
@Data
public 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<E> implements List<E>
@Delegate // @Delegate是lombok注解 ,1.18.6以上版本可支持
@Valid // 一定要加@Valid注解
public List<E> list = new ArrayList<>();
// 一定要记得重写toString方法
@Override
public 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;
@Valid
private Job job;
@Data
public 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 实现接口的各种参数校验
以上是关于Hibernate-Validator 接口参数校验 | 嵌套参数校验的主要内容,如果未能解决你的问题,请参考以下文章
Java:SpringBoot整合hibernate-validator实现入参数据校验
SpringBoot整合Hibernate-Validator校验器
SpringBoot整合Hibernate-Validator校验器