Spring 5.3.8
@PostMapping("/foo/bar")
void doSomething(){..}
@GetMapping("/foo/{id}")
Foo getFoo(@PathVariable Long id) {..}
For
OPTIONS /foo/bar
PartialMatchHelper will return both mappings, but it should only return the PostMapping.
Comment From: happyWilliam0
@Ickbinet Hi, I think it's not a bug, 1.When I followed the issue, the problem did not appear.In fact it will only return one method by HttpMethod. 2.Even if the HttpMethod of the two methods is consistent, a higher match will be returned after sorting. 3.PartialMatchHelper is used to print partial matching infromation when there is no matching.
Comment From: Ickbinet
Hm... which spring version do you use? I tested with 2.5.6.
I got:
$ curl -i -X OPTIONS localhost:8081/foo/bar
HTTP/1.1 200
Allow: POST,GET,HEAD,OPTIONS
Accept-Patch:
Content-Length: 0
Date: Tue, 09 Nov 2021 11:22:48 GMT
Comment From: happyWilliam0
I tested with 5.2.x and 5.3.x.
Comment From: Ickbinet
Hm, ok, plain Spring, I used Spring Boot 2.5.6
Comment From: Ickbinet
What is the required setup to test it without Boot? war-deployment Tomcat V x.y?
Comment From: bclozel
In case of no match for an incoming request, the PartialMatchHelper
will look at the request and try to loosely find a method that could have matched and throw an informative error - this happens in the RequestMappingInfoHandlerMapping.
As explained in the Javadoc there, we're trying to get all the matching patterns and then consider: * method mismatch * produce/consume mismatch * params mismatch
In this case, OPTIONS /foo/bar
matches both "/foo/bar"
and "/foo/{id}"
patterns, but the latter would fail for params. Note that if the @PostMapping
handler in your sample would have a request body parameter (which is quite common for POST requests), the argument you're making would also apply there and the POST method should not match.
In summary, the PartialMatchHelper
is a best effort mechanism and is trying to catch common mistakes. Right now I don't see a way to consistently honor the behavior you're describing without breaking many, common use cases.
I'm closing this as it is working as designed.