使用MultipartFile作为可选字段的多部分请求-Spring MVC

9

我正在一个J2EE Web应用程序上使用Spring MVC。
我已经创建了一个方法,将请求体绑定到与上述模型相似的模型。

@RequestMapping(value = "/", method = RequestMethod.POST, produces = "application/json")
public AModel createEntity(@Valid @ModelAttribute MyInsertForm myInsertForm) {
    // coding..
}  

一切都很好,当我在MyEntityForm中包含一个MultipartFile类型的属性时,我必须使用内容类型“multipart/form-data”进行请求。这种情况下一切也都很好。
我面临的问题是,我想将MultipartFile属性设置为可选。当客户端请求包含文件时,我的方法可以正常工作,但是当客户端请求不包含文件时,Spring会抛出HTTP状态500错误,错误信息为“Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadException: Stream ended unexpectedly”。
有没有办法解决此问题而不创建两个控制器方法(一个带有MultipartFile,另一个没有)?
3个回答

16

我遇到了同样的问题,只需添加required=false即可解决;因为我并不总是发送文件。请查看以下示例代码:

@RequestMapping(value = "/", method = RequestMethod.POST, produces = "application/json")
public AModel createEntity(@Valid @ModelAttribute MyInsertForm myInsertForm, @RequestParam(value ="file", required=false) MultipartFile file) {
    // coding..
}  

你知道如何在 @PutMapping 中实现相同的功能吗? - Gabriel Brito
如果您想在带有文件的表单中使用此功能,我认为无法使用PUT方法:https://dev59.com/C2Ij5IYBdhLWcg3wUjzG#20388705 - JohnEye

3

试试添加以下内容

(required=false)

在方法签名中添加“multipart”属性。


-1

当您希望使用HTTP发送一个或多个文件时,必须使用多部分请求。这意味着请求的正文将如上所示,

-----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="text"

text default -----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="file1"; filename="a.txt" Content-Type: text/plain

a.txt的内容。

-----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="file2"; filename="a.html" Content-Type: text/html

当您只想发送数据(而不是文件)时,可以将它们作为json、键值对等发送。

Spring框架在您希望将多部分请求映射到对象时使用@ModelAttribute注释。 当您有一个普通的键值请求时,您使用@RequestBody注释。 因此,您不能使MultipartFile可选,因为您必须使用不同的注释。使用两种不同的方法,每种请求类型一个方法,解决了这个问题。例如,

@RequestMapping(value = "/withFile", method = RequestMethod.POST, produces = "application/json")
public ReturnModel updateFile(@ModelAttribute RequestModel rm) {
    // do something.
}

@RequestMapping(value = "/noFile", method = RequestMethod.PUT, produces = "application/json")
public ReturnModel updateJson(@RequestBody RequestModel rm) {
    // do something else.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接