@Valid可以用来标记验证属性和方法返回值,进行级联和递归校验,直接上例子吧
1. @Valid+@NotBlank校验内部类属性2. @Valid+自定义注解校验内部类的属性
1. @Valid+@NotBlank校验内部类属性① 添加@Valid注解,并在需要校验的属性上添加相应的校验注解 :
@Data
public class RequestQo {
@Valid
private List agentList;
@Data
public static class AgentDto {
private String agentId;
// @Valid+@NotBlank在一起才能生效
@NotBlank(message = "agentName不能为空")
private String agentName;
private String agentIp;
}
}
② Controller类中添加@Validate注解
@Controller
public class ValidOperateController {
@PostMapping("/test/valid")
@ResponseBody
public String test(@RequestBody @Validated RequestQo requestQo) {
return "成功";
}
}
如果我们将agentName设置为空:
查看控制台信息:
① 自定义注解@Enum:
@documented
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Enum.List.class)
@Constraint(validatedBy = { EnumValidator.class })
public @interface Enum {
String message() default "{*.validation.constraint.Enum.message}";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
Class> clazz();
String method() default "ordinal";
boolean allowNull() default true;
@documented
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
@interface List {
Enum[] value();
}
}
② 注解校验器:
public class EnumValidator implements ConstraintValidator{ private Enum annotation; @Override public void initialize(Enum constraintAnnotation) { this.annotation = constraintAnnotation; } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { // 如果待校验的值为null,是否校验通过 if (value == null) { return annotation.allowNull(); } // 返回枚举常量的数组:UP,DOWN Object[] objects = annotation.clazz().getEnumConstants(); try { // 获取枚举类中获取校验字段的方法名 Method method = annotation.clazz().getMethod(annotation.method()); for (Object o : objects) { // 将方法执行的结果method.invoke(o)和待校验的值value进行比较,如果相同,说明校验成功 if (value.equals(method.invoke(o))) { return true; } } } catch (Exception e) { throw new RuntimeException(e); } // 如果value没有在枚举值中,校验失败 return false; } }
③ 要校验属性枚举类的取值:
public enum AgentNameEnum {
EDR("edr"),
SIP("sip");
private String value;
AgentNameEnum(String value){
this.value = value;
}
public String getValue() {
return value;
}
}
④ 使用注解校验:
@Data
public class RequestQo {
@Valid
private List agentList;
@Data
public static class AgentDto {
private String agentId;
// @Valid+@Enum在一起才能生效
@Enum(clazz = AgentNameEnum.class,method = "getValue",allowNull = true,message = "agentName只能为edr和sip")
private String agentName;
private String agentIp;
}
}
⑤ 添加@Validated注解:
@Controller
public class ValidOperateController {
@PostMapping("/test/valid")
@ResponseBody
public String test(@RequestBody @Validated RequestQo requestQo) {
return "成功";
}
}
如果agentName为sip :
如果agentName不是edr和sip :
查看控制台信息:



