Spring boot - Request method 'POST' not su

2019-08-15 04:23发布

问题:

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)

回答1:

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);
        }
    }

    }


回答2:

If your @SpringBootApplication annotated class and controller are in different packages it does not pick it by default class scan.

It works in almost all demos because bootstrapping class (@SpringBootApplication annotated class) and rest controller class reside in the same package and loaded to spring context.

// Make your class accessible to spring like this

@SpringBootApplication(scanBasePackageClasses = {GreetingController.class})
public class BootPocApplication {

OR // give the base package name like this

@SpringBootApplication(scanBasePackages = {"com.tryout"})
public class BootPocApplication {


回答3:

For me the issue was that the @RequestBody class was not accessible since it was an internal class.

Making it public/static made it accessible and solved this issue

public static class MyClassDto {
        public String   name;
        public String   comment;
        public String   key;
}


回答4:

For me this error occurred when i used @RequestParam in method definition:

@RequestMapping(value = "/balance",method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
    public FinancialMsgResponse balance(@RequestParam(value = "requestMessage") FinancialMsgRequest requestMessage) throws Exception {

        return new FinancialMsgResponse();
    }

So when i remove the @RequestParam the error

Request method 'POST' not supported

is gone away.

good luck



回答5:

Just follow this

@Controller
@RequestMapping(
        method={RequestMethod.POST,RequestMethod.GET,RequestMethod....} 
    )

public class YourController{
.
.
.
}