Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST API with Multipart File Upload not working for optional parameter

I'm using Spring framework, but not too familiar with it. I'm writing a REST API, specifically a POST method that handles a file upload where the file is optional.

I've tried to simplify the method down but still having a problem. Here is what I have

@RequestMapping(method = RequestMethod.POST, value="/items")
public String create(@RequestParam(value="file", required=false) MultipartFile file) {
    return "Create";
}

The method works fine when I include a file in my form request, however when I don't have a file (as I want it to be optional). I have tried replacing the @RequestParam with a HttpServletRequest parameter yielding the same results.

I get a 500 error with the following stack trace:

java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream ended unexpectedly
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
</pre></p><p><b>root cause</b> <pre>org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream ended unexpectedly
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:99)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.&lt;init&gt;(StandardMultipartHttpServletRequest.java:77)
    org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:76)
    org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1067)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:906)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
</pre></p><p><b>root cause</b> <pre>java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream ended unexpectedly
    org.apache.catalina.connector.Request.parseParts(Request.java:2806)
    org.apache.catalina.connector.Request.parseParameters(Request.java:3096)
    org.apache.catalina.connector.Request.getParameter(Request.java:1145)
    org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:382)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
</pre></p><p><b>root cause</b> <pre>org.apache.tomcat.util.http.fileupload.FileUploadException: Stream ended unexpectedly
    org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:311)
    org.apache.catalina.connector.Request.parseParts(Request.java:2737)
    org.apache.catalina.connector.Request.parseParameters(Request.java:3096)
    org.apache.catalina.connector.Request.getParameter(Request.java:1145)
    org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:382)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
</pre></p><p><b>root cause</b> <pre>org.apache.tomcat.util.http.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    org.apache.tomcat.util.http.fileupload.MultipartStream.readHeaders(MultipartStream.java:480)
    org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:889)
    org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl.&lt;init&gt;(FileUploadBase.java:854)
    org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:259)
    org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:283)
    org.apache.catalina.connector.Request.parseParts(Request.java:2737)
    org.apache.catalina.connector.Request.parseParameters(Request.java:3096)
    org.apache.catalina.connector.Request.getParameter(Request.java:1145)
    org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:382)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

I found only one post in my search on the web and it talks about this potentially being a bug in Spring. I've been stuck on this problem for a while now and would great appreciate some help.

Thanks

like image 834
Geeky Devs Avatar asked Mar 08 '26 15:03

Geeky Devs


1 Answers

Here is the solution I ended up with.

@RequestMapping(method = RequestMethod.POST, value = "/object")
ResponseEntity<Object> create(@RequestParam("is_file") boolean isFile, HttpServletRequest request) {
    if(isFile) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
      MultipartFile file = multipartRequest.getFile("file");
    } else{
      // You can add other parameters (as long as it isn't a multipart parameter) and do other stuff here
    }

}

like image 112
Geeky Devs Avatar answered Mar 10 '26 05:03

Geeky Devs