Dropwizard和验证对象列表

时间:2017-02-23 05:34:25

标签: java validation dropwizard

我有一个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类中获取验证器,以便我自己处理所有这些?

1 个答案:

答案 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