CXF2.1.4 Content Negotiation ---------------------------- Key: CXF-2070 URL: https://issues.apache.org/jira/browse/CXF-2070 Project: CXF Issue Type: Bug Components: Resources, REST Affects Versions: 2.1.4 Environment: CXF2.1.4 Reporter: 梁凯 Fix For: 2.1.4
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()) { return 1; } if (!mt1.isWildcardSubtype() && mt2.isWildcardSubtype()) { return -1; } } return mt1.toString().compareTo(mt2.toString()); } -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.