Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-2070

CXF2.1.4 Content Negotiation

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.1.4
    • 2.1.4, 2.2
    • JAX-RS, Resources
    • None
    • CXF2.1.4

    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())

      { return 1; }

      if (!mt1.isWildcardSubtype() && mt2.isWildcardSubtype())

      { return -1; }


      }
      return mt1.toString().compareTo(mt2.toString());
      }

      Attachments

        Activity

          People

            Unassigned Unassigned
            tomliang 梁凯
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: