弹簧引导中上传多部分/格式文件只能是提后交,而不针对补丁,这个问题花了作者26个小时才解决这个问题,最后不得不调试春源代码来解决这个问题。
需求:在网页中构建一个表单,其中包含一个文本输入字段和一个用于文件上载的输入。很简单。这是表单:
& lt;形式id=笆荨狈椒?安苟 盿ction="/f”比; & lt;输入类型=拔谋尽北匦璧膎ame=肮尽北? & lt;输入类型=拔募币髇ame="定义"/比; & lt;/form>
RestController中的方法:
@RequestMapping (value=" https://www.yisu.com/f ",方法=补丁) 公共空间上传( @RequestPart MultipartFile定义(“定义”), @RequestPart公司(“公司”)字符串 ){…} >之前注意它是补丁的方法(根据要求)而不是,部分要求是提交的ajax请求,并不是表单提交,代码如下:
var fileInput=?//这是html元素保存文件 var textInput=?//这是字符串 var fd=new FormData (); fd.append(“定义”,fileInput.files [0]); fd。追加(“名字”,textInput); xhr=new XMLHttpRequest (); xhr。(“补丁”,uploadForm开放。行动,真正的); xhr。发送(fd); >之前但无论怎么做,我都无法让它发挥作用。总是遇到以下异常:
MissingServletRequestPartException:需要请求“定义”部分不存在
引用>
我做的第一件事就是将这个问题分解为最简单的问题,所以我将请求类型更改为POST,并删除了textInput。将多部分解析器的实现进行更改,从org.springframework.web.multipart.support。StandardServletMultipartResolver改为org.springframework.web.multipart.commons.CommonsMultipartResolver
@ configuration 公开课MyConfig { @ bean 公共MultipartResolver MultipartResolver () { 返回新CommonsMultipartResolver (); } } >之前这还需要将commons-fileupload库添加到类路径中。
但每当我添加一个字符串变量返回错误:字符串字段而不是文件字段
这说明多声部请求解析器没有发现这部分字段。
这是由于Javascript的FormData问题,在FormData对象上调用的附加方法接受两个参数名称和值(有第三个但不重要),该值字段可以是一个USVString或Blob(包括子类等文件)。更改代码为:
var fileInput=?//这是html元素保存文件 var textInput==新团((“信息”),{ 类型:“文本/普通” }); ;//这是字符串 var fd=new FormData (); fd.append(“定义”,fileInput.files [0]); fd。追加(“名字”,textInput); xhr=new XMLHttpRequest (); xhr。(“补丁”,uploadForm开放。行动,真正的); xhr。发送(fd); >之前它突然开始工作:)。
看一下浏览器发送的内容:
——WebKitFormBoundaryHGN3YjdgsELbgmZH
引用>
附加:格式;name="定义";文件名="测试。csv”内容类型:文本/csv
这是一个文件的内容,浏览器隐藏它。
——WebKitFormBoundaryHGN3YjdgsELbgmZH附加项:格式;name="名称"
这是字符串
- - - - - - - - WebKitFormBoundaryHGN3YjdgsELbgmZH
你能注意到内容处置标题中缺少的内容吗?文件名和内容类型。在servlet处理期间,多部分表单变成MultipartFile。在commons-fileupload中有一行:
字符串subContentType=headers.getHeader (CONTENT_TYPE); 如果(subContentType !=null…) {}这是得到的内容类型,如果它是null,则处理是通过不同的路由将我们的上传部分不是转为MultipartFile,而是转换为MultipartParameter(放在不同的地图中,而春天没有找到它),然后弹簧为每个参数创建单独的实例,形成在调用其他方法时实现绑定的表单。
RequestPartServletServerHttpRequest构造函数中可以找到抛出异常的位置:
HttpHeaders header=this.multipartRequest.getMultipartHeaders (this.partName); 如果(标题==null) { 把新MissingServletRequestPartException (partName); } >之前重要的是getMultipartHeaders只查看多部分的文件文件而不是参数参数。
这就是为什么添加具有特定类型的blob解决了问题的原因:
详解弹簧引导中补丁上传文件的问题