Reputation: 125
I have a spring controller :
@RequestMapping(value = "bulk", method = RequestMethod.POST)
@ResponseBody
public APIResponse createBulkEnquiries(@Valid @RequestBody List<BulkDTO> bulkDTOs) {
// some code
}
It is not validating any of the bulkDTOs as @valid do not work on element of Collection directly (although BulkDTO is validatable). Also I can not wrap List in some other class (which works) like
public class ValidatableObjectsCollectionWrapper {
@Valid
List<BulkDTO> bulkDTOs;
}
because it will change input json format. So I need some other way around.
I also tried to make a custom validator for collection
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);
}
}
}
But Don't know how to invoke or bind it on the controller param.
Upvotes: 4
Views: 8761
Reputation: 2054
Actually, this can be achieved using Spring Validation and JSR303.
*Expose a MethodValidationPostProcessor bean.
Annotate your controller class with @Validated (org.springframework.validation.annotation.Validated)
Use the JSR303 validation annotations on your MyEntity fields/methods.
Annotate your RequestBody argument with @Valid (you've already done this in your example).
Add an @ExceptionHandler method to handle MethodArgumentNotValidException. This can be done in the controller or in a @ControllerAdvice class.*
Upvotes: 2
Reputation: 692171
Not sure if it's the only, or the best solution, but you can use a wrapper object, without having to change the JSON, using the @JsonValue
and @JsonCreator
annotations. Here is a complete example:
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());
}
}
Upvotes: 6