无法将类型“ org.springframework.web.multipart.commons.CommonsMultipartFile”的值转换为所需类型


问题内容

我有以下控制器方法:

@RequestMapping(value = "/owner/terminals/save", method = RequestMethod.POST)
public String saveTerminal( @RequestParam(value = "name") String name, 
                            @RequestParam(value = "file") @Valid OnlyForImagesFileWrapper file,
                               BindingResult bindingResult )
             {
                ...

我看到以下堆栈跟踪:

    org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'org.springframework.web.multipart.commons.CommonsMultipartFile' to required type 'com.terminal.domain.validation.OnlyForImagesFileWrapper'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.web.multipart.commons.CommonsMultipartFile] to required type [com.terminal.domain.validation.OnlyForImagesFileWrapper]: no matching editors or conversion strategy found
        at           org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:74)
        ....
        Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.springframework.web.multipart.commons.CommonsMultipartFile] to required type [com.terminal.domain.validation.OnlyForImagesFileWrapper]: no matching editors or conversion strategy found
            at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
            ... 71 more

OnlyForImagesFileWrapper来源:

public class OnlyForImagesFileWrapper {
    @Extensions(imageFormats = {".jpg",".png",".gif",".bmp"}, videoFormats = {})
    private MultipartFile multipartFile;
    ...
}

如何避免这个问题?

在哪里可以为多部分
文件的此控制器方法设置转换策略?

P.S.

我试图编写我的自定义initbinder:

@InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(CommonsMultipartFile.class, new PropertyEditorSupport() {
            @Override
            public void setValue(Object file) {
                setValue(new OnlyForImagesFileWrapper((MultipartFile) file));
            }
        });
    }

但是,当我提交表单并且看到上面提到的stacktrace时,不会调用此方法。

P.S.

M. Deinum指令执行后的结果(当我在saveTerminal方法内部时):

我也注意到我的initbinder方法没有被调用。

有关我的代码的更多详细信息(在M. Denium建议之后说明):

jsp:

<input type="file" id="newFile" name="file" class="file" size="21.5" accept=".jpg,.png,.gif,.bmp" style="opacity: 0;">

控制器方法的参数:

...
@ModelAttribute @Valid OnlyForImagesFileWrapper wrapper,
                               BindingResult bindingResult,
...

问题答案:

正如我评论的那样,您使事情变得太复杂了。将包装程序更改为以下内容(使用适当的getter和setter)。

public class OnlyForImagesFileWrapper {
    @Extensions(imageFormats = {".jpg",".png",".gif",".bmp"}, videoFormats = {})
    private MultipartFile file;
    private String name;
...
}

然后你的控制器方法

@RequestMapping(value = "/owner/terminals/save", method = RequestMethod.POST)
public String saveTerminal( @ModelAttribute @Valid OnlyForImagesFileWrapper wrapper, BindingResult bindingResult ) { ... }

当然,在配置中,请确保已MultipartFileResolver配置了正确处理MultipartFile参数的配置,如参考指南中所述。