简体   繁体   中英

Multipart Request with MultipartFile as Optional Field - Spring MVC

I am using Spring MVC on a J2EE Web application.
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".
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.
When a client request include a file my method works great but when a client request does not include a file spring throws a

HTTP Status 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

Is there any way to solve this issue without creating two methods on my controller (one with a MultipartFile and another without)?

I had the same issue and just adding the required=false worked for me. 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.

When you wish to send one or more files using HTTP, you have to use multipart request. This means that the body of the request will be like the above,

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

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

Content of a.txt.

-----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="file2"; 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.

Spring framework uses the @ModelAttribute annotation when you wish to map a multipart request to an object. When you have a normal key-value request, you use the @RequestBody annotation. Thus, you can't have the MultipartFile optional, because you have to use different annotations. 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.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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