Is there any possibility to validate StandardMultipartHttpServletRequest using standard @Valid annotation and custom Validator?

I've implemented such validator, annotated method param in controller the validator is not invoked.

7

1 Answer

I've figured it out myself. To make it work you need a DTO:

import lombok.Getter; import lombok.Setter; import org.springframework.web.multipart.MultipartFile; import java.util.List; @Getter @Setter public class NewOrderFilesDTO { List<MultipartFile> files; } 

Then, a validator:

import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.springframework.web.multipart.MultipartFile; import java.util.List; import static org.springframework.util.CollectionUtils.isEmpty; @Component public class NewOrderFilesValidator implements Validator { private static final String MIME_TYPE_PDF = "application/pdf"; private static final long ALLOWED_SIZE = 3 * 1024 * 1024; @Override public void validate(Object target, Errors errors) { if (target == null) { return; } NewOrderFilesDTO newOrderFilesDTO = (NewOrderFilesDTO) target; List<MultipartFile> newOrderFiles = newOrderFilesDTO.getFiles(); if (isEmpty(newOrderFiles)) { return; } for (MultipartFile file : newOrderFiles) { if (!MIME_TYPE_PDF.equals(file.getContentType())) { errors.rejectValue(file.getName(), file.getName(), "'application/pdf' files allowed only!"); } if (file.getSize() > ALLOWED_SIZE) { errors.rejectValue(file.getName(), file.getName(), "File size allowed up to 3MB!"); } } } @Override public boolean supports(Class<?> cls) { return NewOrderFilesDTO.class.equals(cls); } } 

And finally a controller:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; import javax.validation.Valid; import static org.springframework.http.HttpStatus.NO_CONTENT; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import static org.springframework.web.bind.annotation.RequestMethod.POST; @Controller class OrderController { private final NewOrderFilesValidator newOrderFilesValidator; @Autowired OrderController(NewOrderFilesValidator newOrderFilesValidator) { this.newOrderFilesValidator = newOrderFilesValidator; } @InitBinder("newOrderFiles") void initOrderFilesBinder(WebDataBinder binder) { binder.addValidators(newOrderFilesValidator); } @ResponseStatus(NO_CONTENT) @RequestMapping(value = ORDERS_PATH, method = POST, consumes = MULTIPART_FORM_DATA_VALUE) void createOrder( @Valid @ModelAttribute NewOrderFilesDTO newOrderFiles ) { } } 

With the configuration above the DTO will be validated automatically by spring.

3

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.