title: Spring boot: Request method 'PUT' not supported
body: <p>I am getting a <code>Request method 'PUT' not supported</code> error on hitting a <strong>PUT</strong> method on a restful API to upload a file. </p>
  
  <p>Following is the information uploaded to this ticket. </p>
  
  <ol>
  <li>Client Log  </li>
  <li>RestController</li>
  <li>Spring Boot App Config</li>
  <li>Tomcat log  </li>
  <li>POM.xml</li>
  </ol>
  
  <hr>
  
  <h2>1. Client Log</h2>
  
  <pre><code>$ curl -X PUT -T  "/cygdrive/c/a/documents/test.pptx" http://localhost:8080/piranha-storage-service/buckets/gnaval.bucket1/test.pptx
  &lt;html&gt;&lt;head&gt;&lt;title&gt;Apache Tomcat/7.0.52 - Error report&lt;/title&gt;&lt;style&gt;&lt;!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--&gt;&lt;/style&gt; &lt;/head&gt;&lt;body&gt;&lt;h1&gt;HTTP Status 405 - Request method 'PUT' not supported&lt;/h1&gt;&lt;HR size="1" noshade="noshade"&gt;&lt;p&gt;&lt;b&gt;type&lt;/b&gt; Status report&lt;/p&gt;&lt;p&gt;&lt;b&gt;message&lt;/b&gt; &lt;u&gt;Request method 'PUT' not supported&lt;/u&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;description&lt;/b&gt; &lt;u&gt;The specified HTTP method is not allowed for the requested resource.&lt;/u&gt;&lt;/p&gt;&lt;HR size="1" noshade="noshade"&gt;&lt;h3&gt;Apache Tomcat/7.0.52&lt;/h3&gt;&lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <hr>
  
  <h2>2. RestController</h2>
  
  <pre><code>package com.acme.piranha.api.impl;
  
  import java.io.BufferedOutputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.tomcat.util.http.fileupload.IOUtils;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.PathVariable;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestMethod;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.ResponseBody;
  import org.springframework.web.bind.annotation.RestController;
  import org.springframework.web.multipart.MultipartFile;
  
  import com.amazonaws.services.s3.model.Bucket;
  import com.amazonaws.services.s3.model.S3ObjectSummary;
  import com.acme.piranha.api.PiranhaStorageService;
  import com.acme.piranha.dto.TransferStream;
  import com.acme.piranha.exception.PiranhaDataAccessException;
  import com.acme.piranha.s3.svc.S3;
  
  @RestController
  @RequestMapping(value = "/piranha-storage-service")
  public class PiranhaStorageServiceRESTImpl implements PiranhaStorageService {
  
      @Autowired
      S3 s3;
  
      @RequestMapping(value = "/buckets/{bucketName}/{objectName:.+}", method = RequestMethod.PUT, headers="{Accept=*/*, content-type=multipart/form-data}")
      public @ResponseBody
      String upload(@PathVariable final String bucketName,
              @PathVariable final String objectName,
              @RequestParam("file") MultipartFile file) {
  
          LOG.info("Reached upload. uploading object.");
  
          try {
              File uploadedFile = new File(file.getOriginalFilename());
              try {
                  byte[] bytes = file.getBytes();
                  BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(uploadedFile));
                  stream.write(bytes);
                  stream.close();
              } catch (IOException e) {
                  throw new RuntimeException("Failed to upload file!", e);
              }
              final FileInputStream fileUpload = new FileInputStream(uploadedFile);
              final String objectTag = s3.upload(bucketName, objectName, fileUpload);
  
              LOG.info("Successfully uploaded object to S3, assigned object tag="
                      + objectTag);
              return objectTag;
  
          } catch (final IOException ioe) {
              LOG.error("Failed upload operation, returning empty string");
              // in case of exception flow return a empty stream.
              return "";
  
          } catch (final PiranhaDataAccessException pdae) {
              LOG.error("Failed upload operation, returning empty string");
              // in case of exception flow return a empty stream.
              return "";
          }
  
      }
  }
  </code></pre>
  
  <hr>
  
  <h2>3. Spring Boot App Config</h2>
  
  <pre><code>package com.acme.piranha.config;
  
  import javax.servlet.MultipartConfigElement;
  
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  import org.springframework.boot.builder.SpringApplicationBuilder;
  import org.springframework.boot.context.embedded.MultiPartConfigFactory;
  import org.springframework.boot.context.web.SpringBootServletInitializer;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.ComponentScan;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.web.multipart.MultipartResolver;
  import org.springframework.web.multipart.commons.CommonsMultipartResolver;
  
  @Configuration
  @EnableAutoConfiguration
  @ComponentScan("com.acme.piranha")
  public class PiranhaStorageServiceApplication extends SpringBootServletInitializer {
  
      @Override
      protected SpringApplicationBuilder configure(
              final SpringApplicationBuilder application) {
          return application.sources(PiranhaStorageServiceApplication.class);
      }
  
      public static void main(final String[] args) throws Exception {
          SpringApplication.run(PiranhaStorageServiceApplication.class, args);
      }
  
      @Bean
      public MultipartConfigElement multipartConfigElement() {
          MultiPartConfigFactory factory = new MultiPartConfigFactory();
          factory.setMaxFileSize("2MB");
          factory.setMaxRequestSize("2MB");
          return factory.createMultipartConfig();
      }
  
      @Bean
      public MultipartResolver multipartResolver() {
          return new CommonsMultipartResolver();
      }
  }
  </code></pre>
  
  <hr>
  
  <h2>4. Tomcat log</h2>
  
  <pre><code>2014-04-03 12:44:37.159  INFO 5592 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
  2014-04-03 12:44:37.168  INFO 5592 --- [lication.main()] c.p.p.c.PiranhaStorageServiceApplication : Started PiranhaStorageServiceApplication in 5.423 seconds (JVM running for 11.60
  8)
  2014-04-03 12:44:51.995 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing servlet 'dispatcherServlet'
  2014-04-03 12:44:51.997  INFO 5592 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
  2014-04-03 12:44:51.998  INFO 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
  2014-04-03 12:44:51.999 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Using MultipartResolver [org.springframework.web.multipart.support.StandardServl
  etMultipartResolver@1c15b988]
  2014-04-03 12:44:52.007 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Unable to locate LocaleResolver with name 'localeResolver': using default [org.s
  pringframework.web.servlet.i18n.AcceptHeaderLocaleResolver@30ab6fdf]
  2014-04-03 12:44:52.014 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Unable to locate ThemeResolver with name 'themeResolver': using default [org.spr
  ingframework.web.servlet.theme.FixedThemeResolver@3696a572]
  2014-04-03 12:44:52.025 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': usi
  ng default [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@57dc2acc]
  2014-04-03 12:44:52.032 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Unable to locate FlashMapManager with name 'flashMapManager': using default [org
  .springframework.web.servlet.support.SessionFlashMapManager@5e2cc0ac]
  2014-04-03 12:44:52.033 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext
   attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
  2014-04-03 12:44:52.033  INFO 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 34 ms
  2014-04-03 12:44:52.037 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Servlet 'dispatcherServlet' configured successfully
  2014-04-03 12:44:52.060 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/pir
  anha-storage-service/buckets/gnaval.bucket1/PivotalInstall.pptx]
  2014-04-03 12:44:52.065 DEBUG 5592 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /piranha-storage-service/buckets/gnaval.bucke
  t1/PivotalInstall.pptx
  2014-04-03 12:44:52.073 DEBUG 5592 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/piranha-storage-service/buckets/gnaval.bucket1
  /PivotalInstall.pptx]
  2014-04-03 12:44:52.075 DEBUG 5592 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/piranha-storage-service/buckets/gnaval.bucket1/P
  ivotalInstall.pptx] are [/**]
  2014-04-03 12:44:52.076 DEBUG 5592 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/piranha-storage-service/buckets/gnaval.buck
  et1/test.pptx] are {}
  2014-04-03 12:44:52.080 DEBUG 5592 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/piranha-storage-service/buckets/gnaval.bucket1/test.pptx] to
   HandlerExecutionChain with handler [org.springframework.web.servlet.resource.ResourceHttpRequestHandler@19db7f7e] and 1 interceptor
  2014-04-03 12:44:52.083 DEBUG 5592 --- [nio-8080-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [org.springframework.web.servlet.resource.Resou
  rceHttpRequestHandler@19db7f7e]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
  2014-04-03 12:44:52.086 DEBUG 5592 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [org.springframework.web.servlet.resource.Resou
  rceHttpRequestHandler@19db7f7e]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
  2014-04-03 12:44:52.089  WARN 5592 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound             : Request method 'PUT' not supported
  2014-04-03 12:44:52.096 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': a
  ssuming HandlerAdapter completed request handling
  2014-04-03 12:44:52.098 DEBUG 5592 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Successfully completed request
  </code></pre>
  
  <hr>
  
  <h2>5. pom.xml</h2>
  
  <pre><code>    &lt;parent&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
  &lt;version&gt;1.0.0.RELEASE&lt;/version&gt;
  &lt;/parent&gt;&lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
              &lt;artifactId&gt;core&lt;/artifactId&gt;
              &lt;version&gt;0.9.3&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
              &lt;artifactId&gt;spring-service-connector&lt;/artifactId&gt;
              &lt;version&gt;0.9.3&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
              &lt;artifactId&gt;cloudfoundry-connector&lt;/artifactId&gt;
              &lt;version&gt;0.9.3&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;commons-lang&lt;/groupId&gt;
              &lt;artifactId&gt;commons-lang&lt;/artifactId&gt;
              &lt;version&gt;2.3&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;commons-collections&lt;/groupId&gt;
              &lt;artifactId&gt;commons-collections&lt;/artifactId&gt;
              &lt;version&gt;3.0&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.amazonaws&lt;/groupId&gt;
              &lt;artifactId&gt;aws-java-sdk&lt;/artifactId&gt;
              &lt;version&gt;1.0.002&lt;/version&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  &lt;/project&gt;
  </code></pre>