Now mime types with suffix (and wildcard subtypes with suffix) are not compatible with wildcard subtypes.
For example, mime type application/*
is not compatible with application/vnd+json
.
This may lead to some surprising results -- for example:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class DemoController {
@GetMapping(path = "/demo", produces = "application/vnd+json")
public void demo() {
}
}
returns 406 error when client requests for a "application/*" mime type
$ curl --header "Accept: application/*" http://localhost:8080/demo
{"timestamp":"2020-07-01T06:40:44.644+0000","status":406,"error":"Not Acceptable","message":"Could not find acceptable representation","path":"/demo"}
I am not sure is this bug or feature according to some standards, but the Javadoc for MimeType.isCompatibleWith
says:
In effect, this method is similar to
includes
, except that it is symmetric."
But at the same time MimeType.includes
method assumes that application/*
includes application/vnd+json
:
new MimeType("application", "*").isCompatibleWith(new MimeType("application", "vnd+json")); // false
new MimeType("application", "*").includes(new MimeType("application", "vnd+json")); // true
Comment From: lifejwang11
@anton-filatov I guess If you use the produces attribute, you must match it,That's true of the source code,so you may have to add application/* and */*,but But I think this is a bug.
Comment From: sbrannen
When you say "Now mime types with suffix...", do you mean that the behavior you have described is new? If so, in which version of Spring Framework did it work differently?
In any case, I can confirm that the following results in failures for the last two assertions against master
.
MimeType application = new MimeType("application", "*");
MimeType applicationJson = new MimeType("application", "vnd+json");
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(application.isCompatibleWith(application)).isTrue();
softly.assertThat(applicationJson.isCompatibleWith(applicationJson)).isTrue();
softly.assertThat(application.isCompatibleWith(applicationJson)).isTrue();
softly.assertThat(applicationJson.isCompatibleWith(application)).isTrue();
});
Comment From: anton-filatov
Hello!
@lifejwang11, I am not sure if I understand your idea. I am sure that if we consider a "usual" mime types and server can produce application/json, this is correct for client to ask for application/* and server must to match such a request. But I dont't know if some rfc or other standards exists for a "vendor" mime types with suffixes that specify server behaviour for such cases.
@sbrannen, no, when I said about "now", i just meant that "perhaps it should be changed" :)
Comment From: rstoyanchev
Team Decision: The behavior is not intuitive indeed and needs to be investigated and addressed but we are going to do that in 5.3 due to the potential for regressions in existing code that depends on the present behavior.