Description
According to the JAX-RS311 specification(Jun 27,2008 0.9version), section 3.8 Determining the MediaType of Responses
4. Sort A and P in descending order, each with a primary key of q-value and secondary key of specificity 8
(n/m > n/* > /).
that means types with higher quality value should be more specific than types with lower quality value, but in CXF2.1.4 implementation.
public final class JAXRSUtils {
...
public static int compareMediaTypes(MediaType mt1, MediaType mt2) {
if (mt1.equals(mt2))
{ float q1 = getMediaTypeQualityFactor(mt1.getParameters().get("q")); float q2 = getMediaTypeQualityFactor(mt2.getParameters().get("q")); int result = Float.compare(q1, q2); return result == 0 ? result : ~result; }if (mt1.isWildcardType() && !mt2.isWildcardType())
{ return 1; }if (!mt1.isWildcardType() && mt2.isWildcardType()) { return -1; }
if (mt1.getType().equals(mt2.getType())) {
if (mt1.isWildcardSubtype() && !mt2.isWildcardSubtype()) { return 1; }
if (!mt1.isWildcardSubtype() && mt2.isWildcardSubtype()) { return -1; }
}
return mt1.toString().compareTo(mt2.toString());
}
...
}
The content-negotiation algorithm of CXF2.1.4 seems to take quality value into account only when comparing equivalent MediaTypes.
As a result, for the @ProduceMime{ "application/xml;q=0.9", "application/json;q=0.5" }, the "application/json;q=0.5" is preferred, which
does not respect the JAX-RS311 specification.
So, I suggest change the compareMediaTypes method as follows to meet the JAX-RS311 specification.
public static int compareMediaTypes(MediaType mt1, MediaType mt2) {
float q1 = getMediaTypeQualityFactor(mt1.getParameters().get("q"));
float q2 = getMediaTypeQualityFactor(mt2.getParameters().get("q"));
int result = Float.compare(q1, q2);
if (result != 0)
return ~result;
if (mt1.isWildcardType() && !mt2.isWildcardType()) { return 1; }
if (!mt1.isWildcardType() && mt2.isWildcardType())
{ return -1; } if (mt1.getType().equals(mt2.getType())) {
if (mt1.isWildcardSubtype() && !mt2.isWildcardSubtype())
if (!mt1.isWildcardSubtype() && mt2.isWildcardSubtype())
{ return -1; }
}
return mt1.toString().compareTo(mt2.toString());
}