前言
平常开发接口中,有大量重复的参数合法性校验,例如:
@GetMapping("/query")
public Result query(QueryDTO queryDTO) {
if (queryDTO.getId() == null){
return Result.error("请求 ID 为空");
} else if (StringUtils.isEmpty(queryDTO.getName())){
return Result.error("请求 NAME 为空");
}
// 业务逻辑
}
参数众多,校验方式也各为不同,代码难免变得臃肿。
Spring Validation
Spring Validation 是一种基于 Spring 的参数校验工具,常用于 Spring MVC 中 Controller 的参数处理。常用校验注解如下:
注解 | 说明 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Past | 限制必须是一个过去的日期 |
使用 Spring Validation 需要添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
使用 BindingResult
BindingResult 用于收集 validation 校验结果信息,例:
@GetMapping("/query")
public Result query(@Valid QueryDTO queryDTO, BindingResult bindingResult) {
if (bindingResult.hasErrors()){
return Result.error("未知异常");
}
// 业务逻辑
}
全局异常捕获
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BindException.class)
public Object handleBindException(BindException ex) {
FieldError fieldError = ex.getFieldError();
return Result.error(fieldError.getDefaultMessage());
}
}
自定义校验器
自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
// 指定注解处理类
@Constraint(validatedBy = MyValidation.class)
public @interface MyAnnotation {
String message();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
注解处理类
public class MyValidation implements ConstraintValidator<MyAnnotation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
// 自定义校验逻辑
return true;
}
}