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.

Reply via email to