当前位置: 首页 > 知识库问答 >
问题:

@应用于MultipartFile对象时,将忽略有效注释

郑安晏
2023-03-14

这是我的控制器。它接受带有两个字段的Multipart/form-data请求,formfileform字段是MyObjectfile字段是MultipartFile。这两个变量都用@Valid注释,因此,我希望Spring调用每个相应字段的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);
    }
}

MyMyObjectValidator被触发,但MyFileValidator未被触发。这两个类都实现了SpringValidator接口<代码>MyObjectValidator。支持(类)

这里可能有什么问题?我读过类似的问题,常见的错误是在@InitBinder注释中没有使用适当的参数,或者将@InitBinder方法设置为private,而不是html" target="_blank">public,但这两者都不适用于我的情况。

这个丑陋的变通方法做了它应该做的,但它不像Spring。我在Controller.createMyObject方法中手动调用我的FileValidator,而不是让Spring通过@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.
    }
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.
    }

编辑:我像NiVeR建议的那样对代码做了一些更改,删除了varargs参数,并更改了我的FileValidator.supports(类

在Controller.java:

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

在FileValidator中。爪哇:

public boolean supports(Class<?> aClass) {
    return MultipartFile.class.isAssignableFrom(aClass);
}

共有2个答案

彭嘉赐
2023-03-14

我认为你必须在所有的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.
    }
}
张嘉熙
2023-03-14

我相信这个问题与变量多部分有关 参数。在验证器的supports方法中,您正在检查多部分数组,但我怀疑这不是正确的方法。作为一个试验,我将把Multipart作为单个对象参数(并相应地更改验证器),以测试它是否以这种方式工作。

 类似资料:
  • 我在我的应用程序中使用带有陶土的ehcache。当我使用带有陶土的ehcache时,我的响应时间增加了700倍。我认为陶土需要时间来测量物体的大小,因为它给了我警告: net.sf.ehcache.pool.sizeof。ObjectGraphWalker checkMaxDepth警告:在尝试计算对象图的大小时,已达到1000个对象引用的配置限制。如果继续调整大小操作,可能会出现严重的性能下降。

  • 问题内容: 我的主要课程是 控制器 JSP页面 为什么对象字段未通过AddressForm验证? 请帮忙。 问题答案: 您需要用注解装饰的成员。请参阅《JSR 303:Bean验证》的 3.1.3和3.5.1节。正如我在对问题“ 是否存在使用注释方法启用JSR 303 Bean验证的标准方法”的 回答中所解释的那样,这是根据JSR 303 真正使用注释的方式。 编辑 示例代码:Hibernate

  • 我想在Java中反序列化包含空值的json字符串。我想将对象反序列化为对象。json字符串类似于: 当我反序列化使用 由于对象中的that,我得到一个空指针异常。我如何指示Gson忽略空值的反序列化?

  • 我试图使用Jackson注释来重新命名序列化过程中产生的一些json标签。所有注释都编译得很好,当我运行时,除了所有Jackson注释之外,Jackson序列化工作完全被忽略。即使像@jsonignore或@jsonproperty这样的基本命令对json响应也没有影响。构建路径中的库有: 下面是我需要序列化的一个类的代码示例:

  • 有什么想法为什么@primary在这里没有被考虑在内吗?

  • 在运行Android11+的设备上使用应用程序的开发者必须使用范围存储,以给用户更好的访问控制他们的设备存储。要在5月5日之后在Android 11或更新版本上发布应用程序,您必须: 更新您的应用程序以使用更隐私友好的最佳实践,如存储访问框架或媒体存储API更新您的应用程序以声明清单文件中的所有文件访问(MANAGE_EXTERNAL_STORACTA)权限,并从5开始在播放控制台中完成所有文件访