2

This is a spin-off from a previous question, Spring validator class is ignored by controller. I'm struggling to make my controller accept a MultipartFile object and make Spring bind a Validator to this object. Succintly, this does not work:

@RequestMapping("/api")
@RestController
public class Controller{

    private FileValidator fileValidator;

    @Autowired
    public myObjectController(FileValidator fileValidator){
        this.fileValidator = fileValidator;
    }

    @InitBinder("file")
    public void initFileBinder(WebDataBinder binder) {
        binder.setValidator(this.fileValidator);
    }

    @PostMapping("myObject")
    @ResponseStatus(HttpStatus.CREATED)
    @ResponseBody
    public MyObject createMyObject(
        @RequestPart("file") @Valid MultipartFile file
    ){
        return null; //201 CREATED every time
    }
}



public class FileValidator implements Validator{

    public boolean supports(Class<?> aClass) {
        //Breakpoint on line below is never triggered.
        return MultipartFile.class.isAssignableFrom(aClass); 
    }

    public void validate(Object o, Errors e) {
        //validation happening here
    }
}

I'm not the first person on the world wide web to face a similar problem.

http://javabycode.com/spring-framework-tutorial/spring-mvc-tutorial/spring-mvc-file-upload-validation-example.html

https://stackoverflow.com/a/7256042/4640960

https://memorynotfound.com/spring-mvc-file-upload-example-validator/

https://stackoverflow.com/a/13085988/4640960

https://hackinghorse.blogspot.com/2016/08/devnote-uploading-multipart-file-with.html

All examples solve my problem my wrapping the MultipartFile in a very dumb wrapper class in order for the @Valid annotation to work. It seems as if this is necessary, but why is this necessary? I must emphasize that this particular question is not about working around my technical problem, but to understand what it is about MultipartFile that makes these objects ignored by the @Valid annotation.

Magnus
  • 589
  • 8
  • 26
  • 1
    The second answer in your second link seems to suggest a way to do it without any sort of wrapper objects. Did that not work for you? It even has an explanation for the behavior. – CollinD Jul 17 '18 at 14:50
  • 1
    I'm not familiar with the concept of a Spring `Converter`, and the answer did not have enough upvotes for me to dig into it, and the author did not seem convinced his suggestion would work. On top of that, the OP in the second link seems content to use a wrapper class `MyObject`, because that is where his MultipartFile is headed anyways. It seems over the top for me to use a wrapper class for the mere reason of using `@Valid`, and nothing else. Is there an explanation for the behavior? Yes, it is mentioned that MultipartFile is a special paramter, but how, why? – Magnus Jul 17 '18 at 15:06
  • Who cares how many upvotes it has. It's an alternative solution to your issue, maybe it's worth your time to look into it while waiting for a "why" answer. As for not being familiar with spring converters, it's worth looking into it. They're not complex and are a critical part of spring's infrastructure. Besides, if you were familiar with the solution already, you'd have fixed it, so discarding an answer for being unfamiliar is a pretty poor strategy to solving technical issues. – CollinD Jul 17 '18 at 15:35
  • 1
    This question is not about solving an issue. The linked question at the very beginning of the post, however, is. This question is about understanding. – Magnus Jul 17 '18 at 16:18
  • It is the simple fact that @Valid simply doen’t work/applies to @RequestParam/@RequestPart method arguments. It works for complex objects only. Validation (with validators) only works when doing binding. Binding implies binding request parameters to an object. When Using @RequestParam/@RequestPart there is no binding involved, hence no validation like that applies. – M. Deinum Jul 17 '18 at 19:46
  • Ok, thank you for your input. Do you understand why it might apparently have worked with a `@RequestPart` argument, like it did in this earlier question of mine? https://stackoverflow.com/questions/51379247 The `MyObject` was sent through `MyObjectValidator`, whereas the `MultipartFile` was *not* sent through `FileValidator`. When you say complex object, what does it mean exactly? – Magnus Jul 17 '18 at 20:46

0 Answers0