该异常的原因是在
我一直在为一个用于对象列表的自定义验证器而绞尽脑汁。该示例是借用的代码,但使用包装类ValidList嵌入实际列表。现在,当我使用像Size(min=1(这样的ootb注释时,验证就起作用了。但是,如果我使用自定义注释(不要看功能,它只是在这里演示(,我会得到一个500错误的臭名昭著的HV000030:
No validator could be found for constraint 'com.example.demo.validation.ListLength' validating type 'java.util.List<SomePojo>'. Check configuration for 'list'
当我呼叫时
$ curl -H 'Content-Type: application/json' -X POST -d '[{"id":1,"token":"lalala"}]' http://localhost:8080/pojos
(我使用Lombok的@Value来表示getter/setter和不变性(
谁知道出了什么问题?
@RestController
public class SomeController {
@PostMapping("/pojos")
public ValidList<SomePojo> test(@Valid @RequestBody ValidList<SomePojo> pojos) {
return pojos;
}
}
@Value
public class ValidList<SomePojo> {
@JsonValue
@ListLength
//@Size(min=1)
private List<SomePojo> values;
@JsonCreator
public ValidList(SomePojo... items) {
this.values = Arrays.asList(items);
}
}
@Value
public class SomePojo {
int id;
String token;
}
@Documented
@Constraint(validatedBy = ListValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListLength {
String message() default "Not enough pojos";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
ListLength[] value();
}
}
public class ListValidator implements ConstraintValidator<ListLength, List<SomePojo>> {
@Override
public boolean isValid(List<SomePojo> somePojos, ConstraintValidatorContext constraintValidatorContext) {
return somePojos.size() > 1;
}
}
ListValidator
定义中将SomePojo
用作List
的泛型参数。在ConstraintValidator
实现中,应该为泛型类型使用通配符。
从javadoc:复制
实施必须遵守以下限制:
T
必须解析为非参数化类型- 或
T
的泛型参数必须是无限制通配符类型
所以应该将ListValidator
重写为:
public class ListValidator implements ConstraintValidator<ListLength, List<?>> {
@Override
public boolean isValid(List<?> somePojos, ConstraintValidatorContext constraintValidatorContext) {
return somePojos.size() > 1;
}
}
有关更多信息,请参阅ConstraintValidator
javadoc和Bean验证文档。