How to validate file type, size while uploading in Rest in Spring?

John Maclein picture John Maclein · Aug 22, 2015 · Viewed 10.1k times · Source

I am trying to implement file uploading using spring and Rest. Here what I have done this far

@RestController
@RequestMapping("/rest/upload")
public class ProfileImageUploadController {

   @Autowired
   ImageValidator imageValidator;

   @RequestMapping(value="/{userId}/image", method=RequestMethod.POST)
   public @ResponseBody String handleFileUpload(
        @PathVariable("userId") Integer userId,
        @ModelAttribute("image") SingleImageFile image,
        BindingResult result){

       MultipartFile file = image.getFile();
       imageValidator.validate(file, result);
       if(!result.hasErrors()){
           String name = file.getOriginalFilename();
           try{
               file.transferTo(new File("/home/maclein/Desktop/"+name));
               return "You have successfully uploaded " + name + "!";
           }catch(Exception e){
               return "You have failed to upload " + name + " => " + e.getMessage();
           }
       } else {
           return result.getFieldErrors().toString();
       }
   }
}

Here is my ImageValidator

@Component
public class ImageValidator implements Validator {
   @Override
   public boolean supports(Class<?> arg0) {
       // TODO Auto-generated method stub
       return false;
   }

   @Override
   public void validate(Object uploadedFile, Errors error) {
       MultipartFile file = (MultipartFile) uploadedFile;

       if(file.isEmpty() || file.getSize()==0)
           error.rejectValue("file", "Please select a file");
       if(!(file.getContentType().toLowerCase().equals("image/jpg") 
            || file.getContentType().toLowerCase().equals("image/jpeg") 
            || file.getContentType().toLowerCase().equals("image/png"))){
           error.rejectValue("file", "jpg/png file types are only supported");
       }
   }
}

But while testing through postman its showing the error if file is pdf but in a weird way. Here is the string representation of the error

"[Field error in object 'image' on field 'file': rejected value [org.springframework.web.multipart.commons.CommonsMultipartFile@3fc04a65]; codes [jpg/png file types are only supported.image.file,jpg/png file types are only supported.file,jpg/png file types are only supported.org.springframework.web.multipart.MultipartFile,jpg/png file types are only supported]; arguments []; default message [null]]"

I cannot understand why the error list length is 4. My motive is to show error in json if it is not validated.

If there is any standard way to do this kind of validation ? I am new to spring and Rest. So someone please show me the way to achieve the goal.

Answer

Oleksandr Loushkin picture Oleksandr Loushkin · Aug 23, 2015
 protected List<String> extractErrorMessages(BindingResult result) {
        List<String> errorMessages = new ArrayList<>();
        for (Object object : result.getAllErrors()) {
            if (object instanceof FieldError) {
                FieldError fieldError = (FieldError) object;
                errorMessages.add(fieldError.getCode());
            }
        }
        return errorMessages;
    }

Take a look at fieldError methods, probably in your case you should use getField