这是我的控制器。它接受带有两个字段multipart/form-data
和form
的{{1}}请求。 file
字段是一个
form
,MyObject
字段是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);
}
答案 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.
}
}