Using Spring Boot (v1.2.6.RELEASE), I need to accept POST requests for the Controller methods.
@RestController
@RequestMapping(value = "/myWebApp/signup")
public class RegController {
@RequestMapping(value = "/registerFamily", method = { RequestMethod.POST }, headers = {"Content-type=application/json"})
@ResponseBody
public FamilylResponse registerFamily(@RequestBody @Valid FamilyRequest familyRequest){
... }
When I send POST request from REST clients from Chrome/mozilla,the response comes as follows:
{"timestamp":1446008095543,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/myWebApp/signup/registerFamily"}
...
The stack trace is as follows:
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
at org.springframework.web.servlet.support.WebContentGenerator.checkAndPrepare(WebContentGenerator.java:273)
at org.springframework.web.servlet.support.WebContentGenerator.checkAndPrepare(WebContentGenerator.java:251)
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:207)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
Following the response of Spring: not accept POST request under mvc:resources? how to fix that,
I think some other sub class of WebContentGenerator, like WebContentInterceptor, RequestMappingHandlerAdapter should handle the requests for Controllers.
Also while running Junit tests, I found that the RequestMappingHandlerAdapter is handling those requests for Controllers.
But I'm yet to find how to configure this to accept POST requests as well?
Any other better solution should be more than welcome.
EDIT:
Tomcat uses WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter(a subclass of WebMvcConfigurerAdapter) and
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.addResourceHandlers(ResourceHandlerRegistry) does the following:
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
In junit, I have added an empty concrete child class of WebMvcConfigurerAdapter.
and WebMvcConfigurerAdapter.addResourceHandlers(ResourceHandlerRegistry) does nothing.
@Configuration
@EnableWebMvc
public class WebAppContext extends WebMvcConfigurerAdapter {}
@Configuration
@Import({ WebAppContext.class })
@PropertySource("classpath:application.properties")
public class ExampleApplicationContext { }
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ExampleApplicationContext.class})
@WebAppConfiguration
public class RegControllerTest { ... }
It's hard to say what's wrong, because your code seems fine. But I'll try to suggest some small changes, that may help to clarify situation.
At first, you don't need additional @ResponseBody
annotations while you are using @RestController
. From spring site:
Spring 4’s new @RestController annotation, which marks the class as a controller where every method returns a domain object instead of a view. It’s shorthand for @Controller and @ResponseBody rolled together.
Also, the problem may hiding under your headers
requirement. If it is not specific, you can change it to consumes
option. Try the snippet below.
@RequestMapping(value = "/api", method = RequestMethod.POST,
consumes = "application/json", produces = "application/json")
Based on spring doc, the headers
attribute:
The headers of the mapped request, narrowing the primary mapping. Same format for any environment: a sequence of "My-Header=myValue" style expressions, with a request only mapped if each such header is found to have the given value. Expressions can be negated by using the "!=" operator, as in "My-Header!=myValue". "My-Header" style expressions are also supported, with such headers having to be present in the request (allowed to have any value). Finally, "!My-Header" style expressions indicate that the specified header is not supposed to be present in the request.
So, your POST
request will be mapped correctly if and only if a Content-type
header with application/json
value is present. The better approach for limiting Content-Type
would be consumes
attribute. If you were using consumes
attribute, in case of a invalid or missing Content-Type
header, a 415 Unsupported Media Type
would return, which more desirable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With