I'm not sure I understand why it's picking the most specific first. It is clearly the intent from the code, but if I ask for `application/json`, and there's a converter that can return exactly `application/json` and nothing more, then I'd expect that to be what's picked. I don't profess to be an expert on mime types though, so there could certainly be something I'm missing here & a good reason for what it's doing.
What I've been able to find is I can make your example work if I make the following change to your controller.
@GetMapping(value = "/person", produces=MediaType.APPLICATION_JSON_VALUE)
public Person getPerson(@RequestHeader("Accept") final String accept) {
return new Person("test-" + accept, 1.23);
}
Note the addition of `produces` to the annotation.
When you add this, if you send a request with `Accept: application/json` then you will get a response converted by your `com.sample.converter.JsonHttpMessageConverter`, and if you send a request with `Accept: application/json; fmt=tertiary; foo=bar` (or something more specific) it will use the converter registered for that specific media type. I believe this is the behavior you're going for, in that you generally want `application/json` unless the client specifically asks for `application/json;fmt=avro`.
This seems to side step some of the logic related to sorting. With this annotation, the code does not build up a complete list of all media types from all registered converters (it skips the first call to `canWrite()`), instead it just uses a list of one type, what you put in `produces`. It then sorts in the same manner, by specificity, but there's only one media type in the list so it doesn't matter. It will then pick `application/json` and use the corresponding registered message converter.
In the case where you request something more specific, that works because the code will use whichever is more specific, what you set in `produces` or what's in the Accept header. Since the Accept header is more specific, that gets used. What would fail is if you set `produces` to `application/json` but have an Accept header of `plain/text`. Since that's not under the "application/json" hierarchy, it doesn't match and you get an 406.
Anyway, you might give that a try for a workaround. If you think there's a bug in the way it's handling media type selection, like the way it's sorting, I would suggest opening a JIRA issue here -> https://github.com/spring-projects/spring-framework/issues
Hope that helps!