-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docs should warn against split URL handling across handler mappings #24304
Comments
When a request comes in, it is mapped to a I've tried to reproduce your sample and couldn't:
Since the annotated handlers are considered first, they first get a chance to handle that request. Maybe you've got something specific in your Spring MVC setup? Or maybe your Controller class has a All routes defined with mapping annotations are considered within In your case, the So, in summary:
For additional questions, please use StackOverflow. |
Yes, I know that SimpleUrlHandlerMapping can be ranked before RequestMappingHandlerMapping by modifying the order value, and the
This is the result of my local run: $ curl -s -XGET http://localhost:8080/foo
foo $ curl -s -XPOST http://localhost:8080/foo
{"timestamp":"2020-01-07T11:35:52.752+0000","status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/foo"} If you do not modify the default order, the results will be reversed: $ curl -s -XPOST http://localhost:8080/foo
foo $ curl -s -XGET http://localhost:8080/foo
{"timestamp":"2020-01-07T11:38:37.792+0000","status":405,"error":"Method Not Allowed","message":"Request method 'GET' not supported","path":"/foo"} Thanks! |
I'm sorry. Although this may not be reasonable by design, I think it is a bug. After all, the two registration methods support different methods. |
@xiaoqiang0-0 I see how this can be bothering in your case. Unfortunately, the We can solve mapping conflicts withing a |
@bclozel This is demo of using the functional endpoints.
$ curl -s -XPOST http://localhost:9999/foo
POST: foo! $ curl -s -XGET http://localhost:9999/foo
{"timestamp":"2020-01-08T02:35:21.273+0000","status":405,"error":"Method Not Allowed","message":"Request method 'GET' not supported","trace":"org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported\r\n\tat org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:201)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:421)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:449)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:67)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:393)\r\n\tat org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1234)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:634)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.lang.Thread.run(Thread.java:744)\r\n","path":"/foo"}
and result is similar. |
A match by URL is considered a strong enough indication that the matched handler owns the handling of that endpoint URL. This is what enables returning a 405 error from Splitting the handling of a given URL across different handler mappings is always going to be a challenge for this reason. I would definitely encourage avoiding such a split and consolidating for example by creating your own view controller: @Controller
public class MyViewController {
@GetMapping("/foo")
public String foo() {
return "foo";
}
} I think we could maybe add something to the Javadoc of ViewControllerRegistry and/or the MVC config section to warn against splitting the handling of a URL across handler mappings. |
@rstoyanchev Thank you very much for your answer. I also understand that it is not reasonable to write code like this, but unexpected operation found such a problem. However, this problem may actually occur, so I hope at least it can be explained or warned in the documentation.Of course, I hope that in the future, we can solve the problem of splitting the processing of a given URL across different handler mappings. |
I don't see any easy answers to be honest. |
Affects: <5.1.9.RELEASE>
At the same time, through the custom controller and implement org.springframework.web.servlet.config.annotation.WebMvcConfigurer#addViewControllers to register the mapping of different methods with the url, a 405 error will occur.
The text was updated successfully, but these errors were encountered: