一、一般的参数校验怎么做的?

我们知道在Post接受一个对象参数的时候可以使用 @Valid 去验证,然后通过统一异常处理,直接返回给前端,不用在业务代码中对这些参数进行校验。

且约束的类型也有很多,比如:

 

  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max, min) 被注释的元素的大小必须在指定的范围内
  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Past 被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个将来的日期
  • @Pattern(value) 被注释的元素必须符合指定的正则表达式


上面注解实现的约束是spring官方给我们定义好的,好处就是可以直接拿来使用,坏处就是我们自己无法修改,当不满足需求时无法再使用。

因此,很多时候需要自定义注解去实现想要的约束。

二、 自定义注解实现约束

要实现自定义注解实现自己想要的约束,需要借助 @Constraint 注解:

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SelfConstraintValidator.class)
public @interface SelfConstraint {
String message() default "参数超出范围,校验不通过";;
long min();
long max();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class SelfConstraintValidator implements ConstraintValidator<SelfConstraint, Object> {
private long max = 1;
private long min = 1;


public void initialize(SelfConstraint constraintAnnotation) {
max = constraintAnnotation.max();
min = constraintAnnotation.min();
Console.log("SelfConstraintValidator初始化max=" + max + "和min=" + min);
}

public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
if(o == null){
Console.log("参数" + o.toString() + "为空!合法!");
return true;
}
if(o.toString().trim().length()>=min && o.toString().trim().length()<=max) {
Console.log("参数" + o.toString() + "合法!");
return true;
}
Console.log("参数" + o.toString() + "不合法!");
return false;
}
}
@Data
public class DeptDTO {

@SelfConstraint(min = 1, max = 3, message = "错误")
private Long deptNo;

private String dName;

private String dbSource;
}

上面我们已经把自定义注解使用在 deptNo 字段,controller里面使用@Valid注解:

@RestController
@Slf4j
@RequestMapping("/test")
public class TestController {

@PostMapping("/constraintAnnotation")
public void testConstraintAnnotation(@Valid @RequestBody DeptDTO deptDTO) {
Console.log(deptDTO.toString());
}
}

参数合法时: 

自定义注解实现参数验证 —— @Constraint 注解_异常处理 

自定义注解实现参数验证 —— @Constraint 注解_异常处理_02

参数不合法时:  

自定义注解实现参数验证 —— @Constraint 注解_异常处理_03

自定义注解实现参数验证 —— @Constraint 注解_异常处理_04

当然,可以结合统一异常处理去统一处理验证信息。