Hello Ron,
We spent some time evaluating our algorithm and found that it returns the expected result in the majority of cases. This one is a bit tricky because there's an overlap between the accept type patterns, and that typically results in ambiguity and less than ideal results.
If anyone has a suggestion on how to improve the algorithm (while keeping it simple!), we should file a JIRA for an update release. Designing a simple algorithm that will result in the expected results for all possible cases (including the one in question) isn't easy, but there's always room for improvement, of course.
Thanks.
-- Santiago
On Dec 5, 2013, at 12:13 PM, Ron Sigal <rsigal_at_redhat.com> wrote:
> We've had a lengthy discussion about media type negotiation on https://issues.jboss.org/browse/RESTEASY-994, and I have a question.
>
> The discussion started with the observation by a user, Erik Mattheis, that, given
>
> Accept: application/json, */*
>
> the result returned by
>
> @GET
> @Path("automatic")
> @Produces({ APPLICATION_JSON, APPLICATION_XML })
> public Holder automatic()
> {
> return ...
> }
>
> is in JSON format, but
>
> @GET
> @Path("variant")
> @Produces({ APPLICATION_JSON, APPLICATION_XML })
> public Holder variant()
> {
> List<Variant> XML_OR_JSON = Variant.mediaTypes(APPLICATION_XML_TYPE, APPLICATION_JSON_TYPE).build();
> System.out.println("selected variant: " + request.selectVariant(XML_OR_JSON));
> }
>
> prints
>
> selected variant: Variant[mediaType=application/xml, language=null, encoding=null]
>
> Now, assuming that Request.selectVariant() is governed by http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1, according to which "application/json" and "application/xml" both have an implicit quality factor of 1.0, and given that http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 has no discussion of the breaking of ties, I believe that Resteasy isn't violating the spec when Request.selectVariant() chooses "application/xml". On the other hand, it seems REASONABLE to select "application/json" instead. Does that make sense?
>
> Pursuing the matter further, I have a concern about the algorithm given in Section 3.8 "Determining the media type of responses". Given
>
> Accept: application/*;q=1.0, application/json;q=0.5
> and
>
> @Produces({ "application/json", "application/xml" })
> in Step 6 we get
>
> M = { S("application/*;q=1.0", "application/json"), S("application/*;q=1.0", "application/xml"), S("application/json;q=0.5', "application/json") }
> = { "application/json;q=1.0", "application/xml;q=1.0", "application/json;q=0.5" }
> which can be ordered
>
> "application/json;q=1.0" >= "application/xml;q=1.0" >= "application/json;q=0.5"
> or
>
> "application/xml;q=1.0" >= "application/json;q=1.0" >= "application/json;q=0.5"
> so that either "application/json;q=1.0" or "application/xml;q=1.0" could be returned legally. That seems to be in contradiction to the mandate in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 to use quality factors to select a media type. In particular, "application.json" should have a quality factory of 0.5.
>
> Any comments?
>
> Thanks,
> Ron