Dropwizard 和验证对象列表

Dropwizard and validating lists of objects

我有一个 dropwizard 服务,它接受代表 bean 的 JSON 文档的 PUT。我在 bean 实现中使用约束注释,并在我的资源方法中使用 @Valid 注释:

@PUT
public Response write(@Valid MyBean bean);

一切正常。

但是现在,我想在 JSON 中传递一个 数组 对象。我只是将方法签名更改为

@PUT
public Response write(@Valid List<MyBean> beans);

它通常有效,但如果存在验证错误,则响应不是很友好。例如,如果我 post 在数组中的 100 个 beans 中,并且其中 一个 缺少一个 'name' 属性,那么响应是

{"errors":["name may not be empty"]}

没有任何指示请求中的哪个 bean 有问题。

有办法克服这个问题吗?

如果做不到这一点,我有没有办法在资源 class 中获得一个验证器,以便我自己处理所有这些?

您想要的方式可能无法实现。这是对正在发生的事情以及 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 环境中找到它。为此我使用 DI via Guice)。

如果您想以 DW 方式执行此操作,您可以考虑扩展:JacksonMessageBodyProvider - 这是对 DW 资源进行验证的 class。

希望对你有帮助

您还可以在此处阅读可用的验证选项:https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-message-interpolation.html#section-custom-message-interpolation

-- 阿图尔