SpringMVC文件上传报错:MultipartFile转String类型不匹配问题
错误原因
你提交的表单中存在名为file的文件上传字段,同时你使用@ModelAttribute直接将JPA实体类Documents作为表单绑定对象。Spring MVC在参数自动绑定阶段,会尝试将请求中名为file的MultipartFile类型参数,赋值给Documents实体类中同名的String类型属性,Spring默认没有提供从MultipartFile到String的类型转换器,因此抛出类型转换不匹配异常。该绑定逻辑在进入你编写的控制器方法代码前就会执行,所以你后续手动调用documents.setFile()的代码不会被触发。
解决方案
可以根据业务场景选择以下任意一种方案修复:
方案1:修改文件上传字段命名,避免和实体类字段重名
修改前端表单中文件上传控件的name属性,将原name="file"改为其他名称,例如uploadFile,同步修改控制器中@RequestParam的参数名即可:public ModelAndView add(@ModelAttribute("documentsForm") Documents documents,@RequestParam("uploadFile") MultipartFile file)调整后参数绑定时不会把文件参数匹配到实体类的
file字段,不会触发类型转换错误。方案2:通过
@InitBinder禁止自动绑定实体类的file字段
在当前控制器类中添加如下代码,指定Spring参数绑定时忽略实体类的file字段:@InitBinder public void initBinder(WebDataBinder binder) { binder.setDisallowedFields("file"); }该方案不需要修改前端代码,禁止自动绑定后你后续手动调用
documents.setFile()赋值的逻辑不受影响。方案3:使用单独DTO接收表单参数(规范推荐)
不要直接将JPA实体类作为Web层的参数绑定对象,属于不规范用法,容易出现安全风险和参数绑定冲突。你可以单独定义DocumentFormDTO类接收表单参数,业务处理时手动将DTO属性拷贝到实体类中,从根源上避免持久层对象和Web请求参数的耦合。
内容的提问来源于stack exchange,提问作者Bogdan Onyshenko

