将@Valid注释应用于MultipartFile对象

时间:2018-07-17 10:34:59

标签: java spring spring-boot spring-validator spring-mvc-initbinders

这是我的控制器。它接受带有两个字段multipart/form-dataform的{​​{1}}请求。 file字段是一个 formMyObject字段是file。这两个变量都用MultipartFile注释,因此,我希望Spring可以调用每个相应字段的@Valid类。但是,只有Validator会发生这种情况,MyObject不会发生

MultipartFile

我的@RequestMapping("/api") @RestController public class Controller { private MyObjectRepository repo; private MyObjectValidator myObjectValidator; private FileValidator fileValidator; @Autowired public myObjectController(MyObjectRepository repo, MyObjectValidator myObjectValidator, FileValidator fileValidator) { this.repo = repo; this.myObjectValidator = myObjectValidator; this.fileValidator = fileValidator; } @InitBinder("form") public void initMyObjectBinder(WebDataBinder binder) { binder.setValidator(this.myObjectValidator); } @InitBinder("file") public void initFileBinder(WebDataBinder binder) { binder.setValidator(this.fileValidator); } @PostMapping("myObject") @ResponseStatus(HttpStatus.CREATED) @ResponseBody public MyObject createMyObject(@RequestPart("form") @Valid MyObject myObject, @RequestPart("file") @Valid MultipartFile... file) { return repo.save(myObject); } } 被触发,但是我的MyObjectValidator没有被触发。这两个类都实现了Spring FileValidator接口。 Validator被称为 ,而MyObjectValidator.supports(Class<?> aClass)被称为从未。除此之外,我的FileValidator.supports(Class<?> aClass)运行良好,并努力将对象保存到我的Controller中。

这里可能是什么问题?我读过类似的问题,常见的错误是不在repo批注中使用适当的参数,或者将@InitBinder的方法设置为@InitBinder而不是private,但这都不适合我的情况。

这个丑陋的解决方法可以实现预期的功能,但它与Spring并不一样。我在public方法内手动调用FileValidator,而不是让Spring通过Controller.createMyObject批注自动调用它。

@Valid

编辑:我已应要求提供了@PostMapping("myObject") @ResponseStatus(HttpStatus.CREATED) @ResponseBody public MyObject createMyObject(@RequestPart("form") @Valid MyObject myObject, @RequestPart("file") @Valid MultipartFile... file) { if (fileValidator.supports(file.getClass())) { Errors errors = new BeanPropertyBindingResult(file, "Uploaded file."); fileValidator.validate(file,errors); if (errors.hasErrors()) { throw new BadRequestException(); } } return repo.save(myObject); } 类。

Validator
import org.springframework.validation.Validator;

public abstract class AbstractValidator implements Validator {
    // One shared method here.
}
public class FileValidator extends AbstractValidator {

    public boolean supports(Class<?> aClass) { // This method is never triggered.
        boolean isSingleFile = MultipartFile.class.isAssignableFrom(aClass); // This line has a breakpoint, it is never triggered in the debugger.
        boolean isFileArray = aClass.equals(MultipartFile[].class);
        return (isSingleFile || isFileArray);
    }

    public void validate(Object o, Errors e) {
        //Several validation methods go here.
    }

编辑:我对代码进行了一些更改,如建议的NiVeR,删除了varargs参数并相应地更改了public class MyObjectValidator extends AbstractValidator { public boolean supports(Class<?> aClass) { // This method is triggered. return (MyObject.class.equals(aClass)); // This line has a breakpoint, and it is always triggered in the debugger. } public void validate(Object o, Errors e) { // Several validation methods go here. } ,但是行为仍然相同。

在Controller.java中:

FileValidator.supports(Class<?> aClass)

在FileValidator.java中:

@PostMapping("myObject")
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public MyObject createMyObject(@RequestPart("form") @Valid MyObject myObject, @RequestPart("file") @Valid MultipartFile file) {
    return repo.save(myObject);
}

2 个答案:

答案 0 :(得分:1)

我相信问题与可变参数Multipart...参数有关。在验证器的supports方法中,您正在检查Multipart的数组,但是我怀疑这不是正确的方法。就像试用一样,我会将Multipart设为单个对象参数(并相应地更改验证器)以测试其是否以此方式工作。

答案 1 :(得分:0)

@Magnus我认为您必须在所有Validator类中添加注释 例如。

@Component
public class MyObjectValidator extends AbstractValidator {

    public boolean supports(Class<?> aClass) { //This method is triggered.
        return (MyObject.class.equals(aClass));
    }

    public void validate(Object o, Errors e) {
        //Several validation methods goes here.
    }
}