如何在Spring控制器参数中验证List中的每个对象,而不将List包装在其他类中?

时间:2016-01-03 15:09:12

标签: java spring hibernate

我有一个弹簧控制器:

@RequestMapping(value = "bulk", method = RequestMethod.POST)
@ResponseBody
public APIResponse createBulkEnquiries(@Valid @RequestBody List<BulkDTO> bulkDTOs) {
    // some code 
}

它没有验证任何bulkDTO,因为@valid不能直接对Collection的元素起作用(尽管BulkDTO是可验证的)。 此外,我不能将List包装在其他类(有效)中,如

public class ValidatableObjectsCollectionWrapper {
    @Valid
    List<BulkDTO> bulkDTOs;
}

因为它会改变输入json格式。 所以我需要一些其他方法。

我还尝试为集合制作自定义验证器

public class CollectionValidator implements Validator {

private final SpringValidatorAdapter validator;

public CollectionValidator(SpringValidatorAdapter validator) {
    super();
    this.validator = validator;
}

@Override
public boolean supports(Class<?> clazz) {
    return Collection.class.equals(clazz);
}

@Override
public void validate(Object target, Errors errors) {

    Collection<Object> objectCollection = (Collection<Object>) target;

    for (Object object : objectCollection) {
        validator.validate(object, errors);
    }
}
}

但是不知道如何在控制器参数上调用或绑定它。

2 个答案:

答案 0 :(得分:4)

不确定它是唯一的还是最佳解决方案,但可以使用包装器对象,而无需使用@JsonValue@JsonCreator更改JSON {1}}注释。这是一个完整的例子:

public class BulkDTOWrapper {

    private List<BulkDTO> bulks;

    @JsonCreator
    public BulkDTOWrapper(List<BulkDTO> bulks) {
        this.bulks = bulks;
    }

    public BulkDTOWrapper() {
    }

    @JsonValue
    public List<BulkDTO> getBulks() {
        return bulks;
    }

    public void setBulks(List<BulkDTO> bulks) {
        this.bulks = bulks;
    }

    public static void main(String[] args) throws IOException {
        BulkDTO b1 = new BulkDTO("hello");
        BulkDTO b2 = new BulkDTO("world");

        BulkDTOWrapper wrapper = new BulkDTOWrapper();
        wrapper.setBulks(Arrays.asList(b1, b2));

        ObjectMapper om = new ObjectMapper();
        String json = om.writeValueAsString(wrapper);
        System.out.println("json = " + json);

        BulkDTOWrapper wrapper2 = om.readValue(json, BulkDTOWrapper.class);
        System.out.println(wrapper2.getBulks().size());
    }
}

答案 1 :(得分:0)

实际上,这可以使用Spring Validation和JSR303来实现。

*公开一个MethodValidationPostProcessor bean。

用@Validated(org.springframework.validation.annotation.Validated)注释您的控制器类

在MyEntity字段/方法上使用JSR303验证批注。

用@Valid注释RequestBody参数(在示例中已经完成了此操作)。

添加一个@ExceptionHandler方法来处理MethodArgumentNotValidException。 这可以在控制器中或在@ControllerAdvice类中完成。*