Nikhil Vibhav Nikhil Vibhav - 2 months ago 19
Java Question

Spring boot - Request method 'POST' not supported. Tried everything

I'm building a web application using Spring Boot and MongoDB which will simply perform CRUD operations for employee Documents.

I'm getting this error

"Request method 'POST' not supported"
when I try to hit the create employee endpoint with the json.

My controller class is:

@RestController
@RequestMapping("/employeeapp/employees")
public class EmployeeController {

private final EmployeeService service;

@Autowired
public EmployeeController(EmployeeService service) {
this.service = service;
}

@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public
@ResponseBody
Employee create(@RequestBody @Valid Employee employeeEntry) {
return service.create(employeeEntry);
}

@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
public Employee delete(@PathVariable("id") long id) {
return service.delete(id);
}

@RequestMapping(method = RequestMethod.GET)
public List<Employee> findAll() {
return service.findAll();
}

@RequestMapping(value = "{id}", method = RequestMethod.GET)
public Employee findById(@PathVariable("id") long id) {
return service.findById(id);
}

@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public Employee update(@RequestBody @Valid Employee employeeEntry) {
return service.update(employeeEntry);
}

@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public void handleEmployeeNotFound(EmployeeNotFoundException exception) {
}

}


Application class:

@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}


I've tried disabling
csrf
, adding
@ResponseBody
on the method but nothing seems to work.

EDIT

I'm hitting
http://localhost:8080/employeeapp/employees
with the POST request. The headers include
Content-Type : application/json
and with this json in the body:

{
"id" : 1,
"name" : "nikhil",
"dept" : "DCX"
}


Also, this is what i see in the logs when I hit the above URL with POST request.

2016-02-19 12:21:36.549 INFO 5148 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] :
Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-02-19 12:21:36.549 INFO 5148 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet :
FrameworkServlet 'dispatcherServlet': initialization started
2016-02-19 12:21:36.562 INFO 5148 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet :
FrameworkServlet 'dispatcherServlet': initialization completed in 13 ms
2016-02-19 12:21:36.595 WARN 5148 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound :
Request method 'POST' not supported


EDIT 2:

I checked the Spring boot logs, turns out the mappings are not being generated and instead spring is mapping to default services. Any idea why it might be happening?

[INFO] --- spring-boot-maven-plugin:1.3.2.RELEASE:run (default-cli) @ EmployeeApp ---

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.2.RELEASE)

2016-02-19 14:51:00.690 INFO 5080 --- [ main] app.Application : Starting Application on DIN16003277 with PID 5080 (D:\!Nikhil\Documents\Code\EmployeeApp\target\classes started by nvibhav in D:\!Nikhil\Documents\Code\EmployeeApp)
2016-02-19 14:51:00.693 INFO 5080 --- [ main] app.Application : No active profile set, falling back to default profiles: default
2016-02-19 14:51:00.770 INFO 5080 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@46117566: startup date [Fri Feb 19 14:51:00 IST 2016]; root of context hierarchy
2016-02-19 14:51:01.987 INFO 5080 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2016-02-19 14:51:02.567 INFO 5080 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-02-19 14:51:03.026 INFO 5080 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-02-19 14:51:03.037 INFO 5080 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-02-19 14:51:03.039 INFO 5080 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.30
2016-02-19 14:51:03.172 INFO 5080 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-02-19 14:51:03.173 INFO 5080 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2409 ms
2016-02-19 14:51:03.689 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'metricFilter' to: [/*]
2016-02-19 14:51:03.689 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-02-19 14:51:03.690 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-02-19 14:51:03.690 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-02-19 14:51:03.690 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2016-02-19 14:51:03.691 INFO 5080 --- [ost-startStop-1] .e.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2016-02-19 14:51:03.691 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2016-02-19 14:51:03.691 INFO 5080 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'applicationContextIdFilter' to: [/*]
2016-02-19 14:51:03.692 INFO 5080 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-02-19 14:51:04.011 INFO 5080 --- [ost-startStop-1] b.a.s.AuthenticationManagerConfiguration :

Using default security password: c652ec29-f926-40eb-bb5b-2bd9185bf6a5

2016-02-19 14:51:04.075 INFO 5080 --- [ost-startStop-1] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
2016-02-19 14:51:04.141 INFO 5080 --- [ost-startStop-1] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@71d64e0f, org.springframework.security.web.context.SecurityContextPersistenceFilter@68e32d1f, org.springframework.security.web.header.HeaderWriterFilter@30bd43e4, org.springframework.security.web.authentication.logout.LogoutFilter@6a766ce6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3111b148, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@75e89f1f, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@289e0d8f, org.springframework.security.web.session.SessionManagementFilter@4ec4999b, org.springframework.security.web.access.ExceptionTranslationFilter@3f4e33f9]
2016-02-19 14:51:04.181 INFO 5080 --- [ost-startStop-1] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration$LazyEndpointPathRequestMatcher@7f2a96e1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3ae13235, org.springframework.security.web.context.SecurityContextPersistenceFilter@5f36bdc8, org.springframework.security.web.header.HeaderWriterFilter@658ee520, org.springframework.security.web.authentication.logout.LogoutFilter@1ce1dc64, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@51a29584, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@120723a8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@b2632d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@49cabfed, org.springframework.security.web.session.SessionManagementFilter@6c8e082f, org.springframework.security.web.access.ExceptionTranslationFilter@51f381ff, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3b3223fd]
2016-02-19 14:51:04.399 INFO 5080 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@46117566: startup date [Fri Feb 19 14:51:00 IST 2016]; root of context hierarchy
2016-02-19 14:51:04.471 INFO 5080 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-02-19 14:51:04.472 INFO 5080 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-02-19 14:51:04.506 INFO 5080 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-02-19 14:51:04.506 INFO 5080 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-02-19 14:51:04.549 INFO 5080 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-02-19 14:51:04.720 INFO 5080 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2016-02-19 14:51:04.844 INFO 5080 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:5}] to localhost:27017
2016-02-19 14:51:04.845 INFO 5080 --- [localhost:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2, 1]}, minWireVersion=0, maxWireVersion=4, maxDocumentSize=16777216, roundTripTimeNanos=565904}
2016-02-19 14:51:05.243 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.244 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2016-02-19 14:51:05.244 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.245 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.247 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2016-02-19 14:51:05.247 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.250 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.251 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2016-02-19 14:51:05.251 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.252 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.252 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.253 INFO 5080 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2016-02-19 14:51:05.377 INFO 5080 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-02-19 14:51:05.391 INFO 5080 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2016-02-19 14:51:05.561 INFO 5080 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-02-19 14:51:05.567 INFO 5080 --- [ main] app.Application : Started Application in 5.207 seconds (JVM running for 11.036)

Answer

Following might help.

  1. While you deploy the application, spring boot displays all the available services on the console. Check the POST method to create is being displayed or not. Check that there shouldn't be any contradiction with other services. GET/PUT/POST
  2. If there are services not deployed, try adding '/' before other services - GET, PUT, POST.
  3. Adding exception handler(link) to check the client input request to check the POJO structure.
  4. Check the URL - If any global path for app/name added with configuration.(link)
  5. Try to remove headers - Content-Type in the request header and post the request again

Following are different things that can happen. Need not to be followed in order.

EDIT:

Run the following to check whether your controller is being enabled and considered by the spring application or not.

import java.util.Arrays;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }

    }