我有一个dropwizard服务,它接受代表bean的JSON文档的PUT。我在bean实现中使用约束注释,并在我的Resource方法中使用@Valid注释:
@PUT
public Response write(@Valid MyBean bean);
一切都运作良好。
然而,现在,我想在JSON中传递数组对象。我只是将方法签名更改为
@PUT
public Response write(@Valid List<MyBean> beans);
它通常有效,但如果存在验证错误,则响应不是非常用户友好。例如,如果我在数组中发布了100个bean,并且其中一个缺少一个&#39;名称&#39;属性,然后响应是
{"errors":["name may not be empty"]}
请求中没有任何哪个 bean有问题。
有没有办法克服这个问题?
如果失败了,我有没有办法在Resource类中获取验证器,以便我自己处理所有这些?
答案 0 :(得分:0)
您可能无法实现此目标。以下是对正在发生的事情的独立测试,以及Hibernate如何与您联系:
public class ListBeanValidationTest {
public static void main(String[] args) {
List<Bean> asList = Arrays.asList(new Bean("test"), new Bean("test2"));
Validator v = Validators.newConfiguration().messageInterpolator(new MsgInterpolator()).buildValidatorFactory().getValidator();
// this is what DW does but i am lazy so you get the main version
if(asList instanceof Iterable) {
Iterable values = (Iterable) asList;
Set<ConstraintViolation<Object>> violations = new HashSet<>();
for(Object value : values) {
violations.addAll(v.validate(value));
}
violations.forEach(System.out::println);
}
}
public static class Bean {
Bean(String name) {
this.name = name;
}
String name;
@NotEmpty(message="bean not empty ${name}")
String wrong;
}
public static class MsgInterpolator implements MessageInterpolator {
@Override
public String interpolate(String messageTemplate, Context context) {
return interpolate(messageTemplate, context, Locale.getDefault());
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
Object validatedValue = context.getValidatedValue();
return null;
}
}
}
MessageInterpolator
是问题所在。它在为你插入消息时没有bean的实例,所以遗憾的是你不能使用它的引用。这意味着你必须以另一种方式做到这一点。
您可以获得对validator
的引用(您如何做到这一点,您可以在DW环境中找到它。我通过Guice
使用DI)。
如果您想以DW方式执行此操作,可以查看扩展:JacksonMessageBodyProvider
- 这是对DW资源进行验证的类。
我希望有帮助
您还可以在此处阅读可用的验证选项:https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-message-interpolation.html#section-custom-message-interpolation
- artur