简体   繁体   English

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

[英]Multipart Request with MultipartFile as Optional Field - Spring MVC

I am using Spring MVC on a J2EE Web application. 我在J2EE Web应用程序上使用Spring MVC。
I have created a method that bounds the request body to a model like the above 我创建了一个方法,将请求体绑定到如上所述的模型

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

Everything are working great and when i include a property of type MultipartFile in the MyEntityForm, then i have to make the request with content type "multipart/form-data". 一切都很好,当我在MyEntityForm中包含MultipartFile类型的属性时,我必须使用内容类型“multipart / form-data”发出请求。
Also, everything are working great with this scenario too. 此外,一切都很适合这种情况。

The problem i am facing is that i would like to have the MultipartFile property as optional. 我面临的问题是我想将MultipartFile属性作为可选项。
When a client request include a file my method works great but when a client request does not include a file spring throws a 当客户端请求包含文件时,我的方法很有效,但是当客户端请求不包含文件时,spring会抛出一个

HTTP Status 500 - Request processing failed; HTTP状态500 - 请求处理失败; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; 嵌套异常是org.springframework.web.multipart.MultipartException:无法解析多部分servlet请求; nested exception is org.apache.commons.fileupload.FileUploadException: Stream ended unexpectedly 嵌套异常是org.apache.commons.fileupload.FileUploadException:Stream意外结束

Is there any way to solve this issue without creating two methods on my controller (one with a MultipartFile and another without)? 有没有办法解决这个问题而不在我的控制器上创建两个方法(一个有MultipartFile而另一个没有)?

I had the same issue and just adding the required=false worked for me. 我有同样的问题,只是添加了required=false为我工作。 Please find the sample code below, 请在下面找到示例代码,

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

Give a try by adding 尝试添加

(required=false)

to multipart property in method signature. 到方法签名中的multipart属性。

When you wish to send one or more files using HTTP, you have to use multipart request. 如果希望使用HTTP发送一个或多个文件,则必须使用多部分请求。 This means that the body of the request will be like the above, 这意味着请求的主体将如上所述,

-----------------------------9051914041544843365972754266 Content-Disposition: form-data; ----------------------------- 9051914041544843365972754266 Content-Disposition:form-data; name="text" NAME = “文本”

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

Content of a.txt. a.txt的内容。

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

When you wish to send only data (and not files) you can send them as json, key-value pairs etc. 当您只想发送数据(而不是文件)时,可以将它们作为json,键值对等发送。

Spring framework uses the @ModelAttribute annotation when you wish to map a multipart request to an object. 当您希望将多部分请求映射到对象时,Spring框架使用@ModelAttribute批注。 When you have a normal key-value request, you use the @RequestBody annotation. 如果您有正常的键值请求,则使用@RequestBody注释。 Thus, you can't have the MultipartFile optional, because you have to use different annotations. 因此,您不能选择MultipartFile,因为您必须使用不同的注释。 Using two different methods, one per request type, solves the issue. 使用两种不同的方法,每种请求类型一种,解决了这个问题。 Example, 例,

@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.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM