10

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)?

3 Answers 3

16

I had the same issue and just adding the required=false worked for me; because, I don't send a file all the time. 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.. } 
Sign up to request clarification or add additional context in comments.

2 Comments

do you know how to implement the same for a @PutMapping ?
@GabrielBrito If you want this for a form with a file, I think it's not possible to use PUT: stackoverflow.com/a/20388705/1084813
3

Give a try by adding

(required=false) 

to multipart property in method signature.

Comments

-1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.