This issue was opened based on the discussion in #27999.
Given the following controller:
@RestController
@RequestMapping("/hal-documents")
class MyController {
@PostMapping(
consumes = ["""application/hal+json;profile="my-resource-v1""""],
produces = ["""application/hal+json;profile="my-resource-v1""""]
)
fun postVersion1(@RequestBody request : String) = "version-1"
@PostMapping(
consumes = ["""application/hal+json;profile="my-resource-v2""""],
produces = ["""application/hal+json;profile="my-resource-v2""""]
)
fun postVersion2(@RequestBody request : String) = "version-2";
}
A request that provides a request body with the content type application/hal+json;profile="my-resource-v2"
is being routed to postVersion1
but should be routed to postVersion2
.
Even worse, if the consumes
media type only differs in media type parameters and the handler methods can't be ranked by produces
an Ambiguous handler methods mapped for ...
error will be thrown leading to a 500er.
Example
Controller:
@RestController
@RequestMapping("/hal-documents")
class MyController {
@PostMapping(
consumes = ["""application/hal+json;profile="my-resource-v1""""]
)
fun postVersion1(@RequestBody request : String) = "version-1"
@PostMapping(
consumes = ["""application/hal+json;profile="my-resource-v2""""]
)
fun postVersion2(@RequestBody request : String) = "version-2";
}
Request:
POST http://localhost:8080/hal-documents
Content-Type: application/hal+json;profile="my-resource-v2"
{
"my content" : "blub"
}
Response:
HTTP/1.1 500
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 10 Feb 2022 06:51:58 GMT
Connection: close
{
"timestamp": "2022-02-10T06:51:58.921+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "java.lang.IllegalStateException: Ambiguous handler methods mapped for '/hal-documents': {...}",
"path": "/hal-documents"
}
Looking into the code, it seems like consumes
and produces
are treated differently in ProducesRequestCondition
and ConsumesRequestCondition
when it comes to media type parameters.
Affects: 5.3.15
Comment From: rstoyanchev
We can align consumes
with the produces
condition, along the lines of 8dc535c15c15a71ce29bc21a45e9daeb064dd35e, such that if a media type parameter is explicitly declared in the mapping and the same parameter is also present in the Content-Type
header, then the two must match.
Comment From: rstoyanchev
Fixed in f0e23b66f32055b6ad9515955d9dd2902d38366e but commit message references a different issue by accident.