Hi Santiago,
Thank you for your response.
I was surprised that the algorithm in Section 3.8 of the JAX-RS spec
seems to be inconsistent with the algorithm implicit in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1, which I
described on RESTEASY-994 as
1. Let PO = the partial order on accepted media types induced by "is
less specific than".
2. Add "dummy/dummy;q=0" as the minimal element in PO, where
"dummy/dummy;q=0" is a wildcard like "*/*"
3. For each M in available media types:
Let Q_M = max { q | q is the quality factor of a maximal
element in PO }
4. Let Q = max { Q_M | M in available media types }
5. Let MT = { M | M is an available media type such that M_Q = Q }
6. If no element in MT matches an accepted media type, return a
"406" response.
7. Return an arbitrary element of MT
Actually, there are a couple of gaps in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1:
1. There is no mention of tie breaking in the case that multiple
available media type are assigned the same quality factor. I think that
the consensus on RESTEASY-994 is that the available media type that
matches the more specific requested media range should be given
preference. For example, given
Accept: application/json, */*
application/json and application/xml would both have a quality factor of
1.0, but application/json should be preferred. Step 7 could be changed
to implement tie breaking based on specificity.
2. There is no precise definition of "more specific". For example, I
would expect application/json to be more specific that */*;a=1;b=2;c=3,
but Resteasy currently prefers the latter because it counts the number
of parameters. I think that should be changed with the ordering defined:
media type 1 is more specific than media type 2 if and only if
* media type 1 has a non wildcard type and media type 2 has a
wildcard type, or
* media type 1 has a non wildcard subtype and media type 2 has a
wildcard subtype, or
* media type 1 has more parameters than media type 2
3. It's a minor thing, but there's no suggestion for what to do with
Accept: application/json, application/xml, application/json;q=0.5
Anyway, the way things are, Request.selectVariant() is governed by
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 (I guess),
and negotiation based on the @Produces annotation is governed by Section
3.8 of the JAX-RS spec, and I believe they can legally return different
results. In particular, the JAX-RS algorithm doesn't have a notion of
basing the quality factor of an available media type on the most
specific matching requested media range. For example, given the
somewhat artificial case
Accept; application/json;q=0.5, application/*
and
@Produces("application/json, application/xml")
the HTTP algorithm would assign a quality factor of 0.5 to
application/json because application/json;q=0.5 is more specific than
application/*, but the JAX-RS algorithm gives
M = { S("application/json;q=0.5", "application/json"),
S("application/*", "application/json"), S("application/*",
"application/xml")
= { application/json;q=0.5, application/json;q=1.0,
application/xml;q=1.0 }
where
application/json;q=1.0 >= application/xml;q=1.0 > application/json;q=0.5
and
application/xml;q=1.0 >= application/json;q=1.0 > application/json;q=0.5
are both legal orderings, so that either application/json or
application/xml could be returned.
-Ron
On 12/07/2013 05:15 AM, users-request_at_jax-rs-spec.java.net wrote:
> 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