没有找到用于枚举 springboot 的自定义注释和验证的验证器 java8
no validator found for custom annotation and validation for enum springboot java8
出现此错误 HV000030: No validator could be found for constraint EnumChecker validating type MyEnum Check configuration for ‘myenum’
。
使用此 class 上的注释进行验证,我无法做到 private final String myenum
因为我需要将其用作枚举才能使用枚举中的函数
public class Request {
@EnumChecker(enumclass = MyEnum.class)
private final MyEnum myenum;
}
注释
@Documented
@Constraint(validatedBy = MyEnumValidator.class)
@Target({FIELD, PARAMETER, TYPE, TYPE_USE, TYPE_PARAMETER, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface EnumChecker {
String message() default "must be one of these values";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum> enumClass();
}
验证者
public class MyEnumValidator implements ConstraintValidator<EnumChecker, String> {
private List<String> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.map(Enum::name)
.collect(Collectors.toList());
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return validEnumList.contains(value);
}
}
枚举
public enum MyEnum {
YES, NO;
private static final Map<MyEnum, String> MyEnumConverter =
Map.of(YES, "yes");
public String toMyString() {
return MyEnumConverter.get(this);
}
}
首先删除 myenum
中的 final
修饰符并为该字段创建 setter 和 getter,因为 Jackson
无法绑定来自 http 的值例如向您的 Request
class 请求。
public class Request {
@EnumChecker(enumClass = MyEnum.class)
private MyEnum myenum;
public MyEnum getMyenum() {
return myenum;
}
public void setMyenum(MyEnum myenum) {
this.myenum = myenum;
}
}
然后更改 ConstraintValidator
目标类型以匹配 MyEnum
而不是 String
public class MyEnumValidator implements ConstraintValidator<EnumChecker, MyEnum> {
private List<MyEnum> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.collect(Collectors.toList());
}
@Override
public boolean isValid(MyEnum value, ConstraintValidatorContext context) {
return validEnumList.contains(value);
}
}
测试:我做了以下测试
@RestController
public class MainController {
@PostMapping("/annot")
public String filter(@RequestBody @Valid Request req) {
return req.getMyenum().name();
}
}
我还更改了 MyEnumValidator
的实现以仅查看验证效果并证明它发生了。 (我承认目前这个验证器没有意义。同样使用 only @RequestBody
保证 myenum
can only Have YES
or NO
值否则抛出异常)
public class MyEnumValidator implements ConstraintValidator<EnumChecker, MyEnum> {
private List<MyEnum> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.collect(Collectors.toList());
}
@Override
public boolean isValid(MyEnum value, ConstraintValidatorContext context) {
return validEnumList.contains(value) && value.name().length() == 3;
}
}
无效案例:
堆栈跟踪:
Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String api.sweater.controller.MainController.filter(api.sweater.request.Request): [Field error in object 'request' on field 'myenum': rejected value [NO]; codes [EnumChecker.request.myenum,EnumChecker.myenum,EnumChecker.api.sweater.request.MyEnum,EnumChecker]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [request.myenum,myenum]; arguments []; default message [myenum],class api.sweater.request.MyEnum]; default message [must be one of these values]] ]
出现此错误 HV000030: No validator could be found for constraint EnumChecker validating type MyEnum Check configuration for ‘myenum’
。
使用此 class 上的注释进行验证,我无法做到 private final String myenum
因为我需要将其用作枚举才能使用枚举中的函数
public class Request {
@EnumChecker(enumclass = MyEnum.class)
private final MyEnum myenum;
}
注释
@Documented
@Constraint(validatedBy = MyEnumValidator.class)
@Target({FIELD, PARAMETER, TYPE, TYPE_USE, TYPE_PARAMETER, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface EnumChecker {
String message() default "must be one of these values";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum> enumClass();
}
验证者
public class MyEnumValidator implements ConstraintValidator<EnumChecker, String> {
private List<String> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.map(Enum::name)
.collect(Collectors.toList());
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return validEnumList.contains(value);
}
}
枚举
public enum MyEnum {
YES, NO;
private static final Map<MyEnum, String> MyEnumConverter =
Map.of(YES, "yes");
public String toMyString() {
return MyEnumConverter.get(this);
}
}
首先删除 myenum
中的 final
修饰符并为该字段创建 setter 和 getter,因为 Jackson
无法绑定来自 http 的值例如向您的 Request
class 请求。
public class Request {
@EnumChecker(enumClass = MyEnum.class)
private MyEnum myenum;
public MyEnum getMyenum() {
return myenum;
}
public void setMyenum(MyEnum myenum) {
this.myenum = myenum;
}
}
然后更改 ConstraintValidator
目标类型以匹配 MyEnum
而不是 String
public class MyEnumValidator implements ConstraintValidator<EnumChecker, MyEnum> {
private List<MyEnum> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.collect(Collectors.toList());
}
@Override
public boolean isValid(MyEnum value, ConstraintValidatorContext context) {
return validEnumList.contains(value);
}
}
测试:我做了以下测试
@RestController
public class MainController {
@PostMapping("/annot")
public String filter(@RequestBody @Valid Request req) {
return req.getMyenum().name();
}
}
我还更改了 MyEnumValidator
的实现以仅查看验证效果并证明它发生了。 (我承认目前这个验证器没有意义。同样使用 only @RequestBody
保证 myenum
can only Have YES
or NO
值否则抛出异常)
public class MyEnumValidator implements ConstraintValidator<EnumChecker, MyEnum> {
private List<MyEnum> validEnumList;
@Override
public void initialize(EnumChecker constraintAnnotation) {
validEnumList = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants())
.collect(Collectors.toList());
}
@Override
public boolean isValid(MyEnum value, ConstraintValidatorContext context) {
return validEnumList.contains(value) && value.name().length() == 3;
}
}
无效案例:
堆栈跟踪:
Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String api.sweater.controller.MainController.filter(api.sweater.request.Request): [Field error in object 'request' on field 'myenum': rejected value [NO]; codes [EnumChecker.request.myenum,EnumChecker.myenum,EnumChecker.api.sweater.request.MyEnum,EnumChecker]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [request.myenum,myenum]; arguments []; default message [myenum],class api.sweater.request.MyEnum]; default message [must be one of these values]] ]