我想在API使用对象之前在dropwizard中使用@Valid。但是,对象的所有属性都没有得到验证,因为它似乎没有发生验证?我是否在添加配置以启用它时遗漏了一些内容?
仅供参考:我们已经实现了自己的消息体阅读器,它从javax.ws.rs.ext.MessageBodyReader扩展,用于将JSON映射到对象。
答案 0 :(得分:0)
您需要在MessageBodyReader中存储javax.validation.Validator
对象,并使用它来验证@Valid
方法中使用readFrom()
注释的类。这就是Dropwizard的杰克逊提供商所做的事情。
所以代码看起来像这样:
private static final Class<?>[] DEFAULT_GROUP_ARRAY = new Class<?>[]{ Default.class };
private final XmlMapper mapper;
private final Validator validator;
public MyMessageBodyReader(XmlMapper mapper, Validator validator) {
this.validator = validator;
this.mapper = mapper;
setMapper(mapper);
}
@Override
public Object readFrom(Class<Object> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException {
return validate(annotations, super.readFrom(type,
genericType,
annotations,
mediaType,
httpHeaders,
entityStream));
}
private Object validate(Annotation[] annotations, Object value) {
final Class<?>[] classes = findValidationGroups(annotations);
if (classes != null) {
final Set<ConstraintViolation<Object>> violations = validator.validate(value, classes);
if (!violations.isEmpty()) {
throw new ConstraintViolationException("The request entity had the following errors:",
ConstraintViolations.copyOf(violations));
}
}
return value;
}
private Class<?>[] findValidationGroups(Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (annotation.annotationType() == Valid.class) {
return DEFAULT_GROUP_ARRAY;
} else if (annotation.annotationType() == Validated.class) {
return ((Validated) annotation).value();
}
}
return null;
}
我有一个示例here,我在其中编写了一个带有验证支持的自定义XML Jackson Reader + Writer。