Spring REST API with Multipart File Upload not wor

2019-07-07 12:03发布

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

3条回答
Deceive 欺骗
2楼-- · 2019-07-07 12:21

I had the same issue and just adding the required=false worked for me. Please find the sample code below,

@RequestMapping(method = RequestMethod.POST, value="/items")
public String create(@RequestParam(value ="file", required=false) MultipartFile file) {
    return "Create";
}
查看更多
Bombasti
3楼-- · 2019-07-07 12:31

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
    }

}

查看更多
萌系小妹纸
4楼-- · 2019-07-07 12:32

I can see question is a bit old, but I put my answer here because uploading files topic is always alive. I tested Spring Boot 1.3.5.RELEASE in context of this question. I defined rest service as below and it works when file is not attached to multipart/form-data. I tested service with RestTemplate client.

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<String> upload(@RequestPart(value = "name", required = false) String name,
                                     @RequestPart(value = "file", required = false) MultipartFile file) 
查看更多
登录 后发表回答