title: jQuery and Spring-Boot file upload causes "Required request part 'file' is not present"
body: <p>I have a file I'm trying to upload to my spring-boot microservice. I'm using jQuery to post file using the FormData javascript object.  Spring-boot is not calling my endpoint in my controller due to the failure to match my FormData's file to a RequestParam file.</p>
  
  <p>JavaScript:</p>
  
  <pre><code>var name = "TEST";
  var kml = '&lt;kml&gt;&lt;Document&gt;&lt;Placemark id="' + name + '"&gt;&lt;Point&gt;&lt;coordinates&gt;-69.83701518,47.817278750000014&lt;/coordinates&gt;&lt;/Point&gt;&lt;/Placemark&gt;&lt;/Document&gt;&lt;/kml&gt;';
  // upload the kml file to the server
  var data = new FormData();
  data.append('file', kml);
  $.ajax({
      method: "POST",
      url: "http://localhost:9096/upload/" + name,
      data: data,
      cache: false,
      contentType: false,
      processData: false,
      success: function(data){
          console.log("success", name, data);
      }
  });
  </code></pre>
  
  <p>Here is my Controller code:</p>
  
  <pre><code>@RestController
  public class MicroServiceController {
  
      private Logger logger = LoggerFactory.getLogger(MicroServiceController.class);
  
      @RequestMapping(value="/upload/{name}", method = { RequestMethod.POST })
      public ResponseEntity&lt;?&gt; uploadKML(@PathVariable String name, @RequestParam("file") MultipartFile file ) throws IOException {
          logger.debug("Upload: {}", name);
  
          return new ResponseEntity&lt;Boolean&gt;(true, HttpStatus.OK);
      }
  }
  </code></pre>
  
  <p>Here is the exception:</p>
  
  <pre><code>2017-02-09 11:45:52.860 DEBUG 5521 --- [nio-9096-exec-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'microServiceController'
  2017-02-09 11:45:52.888 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Failed to resolve argument 1 of type 'org.springframework.web.multipart.MultipartFile'
  
  org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
      at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:193) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:109) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
      at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
  
  2017-02-09 11:45:52.889 DEBUG 5521 --- [nio-9096-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;?&gt; com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
  2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;?&gt; com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
  2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity&lt;?&gt; com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
  2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
  2017-02-09 11:45:52.892 DEBUG 5521 --- [nio-9096-exec-1] o.s.web.servlet.DispatcherServlet        : Successfully completed request
  </code></pre>
  
  <p>And here is the request and headers:</p>
  
  <pre><code>Request URL:http://localhost:9096/upload/TEST
  Request Method:POST
  Status Code:400 
  Remote Address:127.0.0.1:9096
  
  Request Headers:
    Accept:*/*
    Accept-Encoding:gzip, deflate, br
    Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
    Cache-Control:no-cache
    Connection:keep-alive
    Content-Length:273
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryM401einBJzuTMVSj
    Host:localhost:9096
    Origin:http://localhost:8090
    Pragma:no-cache
    Referer:http://localhost:8090/
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36
  
  Request Payload
  ------WebKitFormBoundaryM401einBJzuTMVSj
  Content-Disposition: form-data; name="file"
  
  &lt;kml&gt;&lt;Document&gt;&lt;Placemark id="TEST"&gt;&lt;Point&gt;&lt;coordinates&gt;-69.83701518,47.817278750000014&lt;/coordinates&gt;&lt;/Point&gt;&lt;/Placemark&gt;&lt;/Document&gt;&lt;/kml&gt;
  ------WebKitFormBoundaryM401einBJzuTMVSj--
  </code></pre>
  
  <p>And the response JSON:</p>
  
  <pre><code>{"timestamp":1486655346223,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present","path":"/upload/TEST"}
  </code></pre>
  
  <p>To me, it looks like I have the name of the file set to "file", and I am also looking for "file" in the Microservice... but it doesn't appear to make the connection on the spring-boot side.  I'm confused as it all looks like the examples and issues I find on the internet, but I still get the exception.</p>
  
  <p>Any suggestions on what to try next, or where I screwed up is helpful!</p>