Thierry,

This fillter solution worked very nicely. We'll keep it in place for v
1.1.15 and remove it when we go to v 2.0.
Thank you very much.



Thierry Boileau wrote:
> 
> Andrzej,
> 
> the content negotiation algorithm implemented by the Restlet v1.1 is a 
> bit lost when the preference "*/*" has a quality of 1.0.
> Since it loops over the the declared variants, it first calculates the 
> score of the json variant. Since the "*/*" has a quality of 1, the 
> computed score is the highest possible...
> 
> One way is to systematically under valuate the "*/*" preference in a
> filter:
>  class MyFilter extends Filter {
>         @Override
>         protected int beforeHandle(Request request, Response response) {
>             List<Preference<MediaType>> prefs = request.getClientInfo()
>                     .getAcceptedMediaTypes();
>             if (prefs != null && !prefs.isEmpty()) {
>                 for (Preference<MediaType> preference : prefs) {
>                     if (preference.getMetadata().equals(MediaType.ALL)) {
>                         preference.setQuality(0.1f);
>                     }
>                 }
>             }
> 
>             return Filter.CONTINUE;
>         }
>     }
> 
> NB : the conneg algorithm has been updated in the Restlet 2.0 trunk. It 
> systematically sets a quality of 0.001.
> 
> Best regards,
> Thierry Boileau
> 
>  
>> Thierry,
>>
>> That actually changed the request.  Still get JSON though. Restlet
>> content
>> negotiates APPLICATION_JSON. How can we get APPLICATION_XML ?
>>
>>
>> Request:
>> GET /coralreef-resource/file/status?user=greg.savaged&_=1260974638188
>> HTTP/1.1
>> Accept: application/xml, text/xml, */*
>> Accept-Language: en-us
>> x-requested-with: XMLHttpRequest
>> UA-CPU: x86
>> Accept-Encoding: gzip, deflate
>> User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1;
>> .NET
>> CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR
>> 3.0.30618)
>> Host: 10.1.10.166:8181
>> Connection: Keep-Alive
>> Authorization: Basic Z3JlZy5ob2NoYXJkOmJlcmljbw==
>>
>>
>>
>>
>> Thierry Boileau wrote:
>>   
>>> Hi Andrzej
>>>
>>> could you use the "dataType" argument instead of the "beforeSend" one?
>>>
>>> $.ajax({type: 'GET',
>>>         url: myUrl,
>>>         success: onAjaxSuccess,
>>>         error: onAjaxError,
>>>         cache: false,
>>>         dataType: "xml");
>>>
>>>
>>> Best regards,
>>> Thierry Boileau
>>>
>>>     
>>>> Thierry,
>>>>
>>>> 1) Our JQuery Ajax call:
>>>>
>>>> $.ajax({
>>>>                  type: 'GET',
>>>>                  url: myUrl,
>>>>                  success: onAjaxSuccess,
>>>>                  error: onAjaxError,
>>>>                 cache: false,
>>>>                 beforeSend :
>>>> function(xhr){xhr.setRequestHeader('Accept','application/xml')}
>>>>              });
>>>>
>>>> Will generate Accept header of  "*/*, application/xml". We want
>>>> "application/xml".
>>>>
>>>> 2) Our Restlet 1.1.5
>>>>    
>>>> @Override
>>>> public Restlet createRoot() {
>>>>            // Create a router Restlet.
>>>>            Router router = new Router(getContext());
>>>>    
>>>>            // Attach our routers.
>>>>            router.attach("/test", HelloWorldResource.class);
>>>>            router.attach("/file/status", FileStatusResource.class);
>>>>
>>>>            return router;
>>>>    }
>>>>
>>>>
>>>> public FileStatusResource(Context context, Request request, Response
>>>> response) {
>>>>            super(context, request, response);
>>>>            
>>>>            // Read URI query strings.
>>>>            Form form = request.getOriginalRef().getQueryAsForm();
>>>>            if (form != null) {
>>>>                    setUser(form.getFirstValue("user", isIgnoreCase()));
>>>>                    setOriginalUri(form.getFirstValue("originalUri", 
>>>> isIgnoreCase()));
>>>>                    setAction(form.getFirstValue("action", isIgnoreCase()));
>>>>            }
>>>>            
>>>>            // Variants that our resource generates.
>>>>            getVariants().add(new Variant(MediaType.APPLICATION_JSON));
>>>>            getVariants().add(new Variant(MediaType.APPLICATION_XML));
>>>>            
>>>>    }
>>>>
>>>> @Override
>>>> public Representation represent(Variant variant) throws
>>>> ResourceException
>>>> {
>>>>            Representation representation = null;
>>>>            
>>>>            // Validate request
>>>>            if (StringUtils.isBlank(getUser())) {
>>>>                    log.debug("GET FileStatusResource bad user. ");
>>>>                    representation = representError(variant, new 
>>>> ErrorMessage());
>>>>                    
>>>> getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
>>>>                    return representation;
>>>>            }
>>>>            
>>>>            representation = representGet(this,variant);
>>>>            return representation;
>>>>    }
>>>>
>>>> public final Representation representGet(CoralReefResource crr, Variant
>>>> variant)
>>>>                    throws ResourceException {
>>>>            Representation representation = null;
>>>>
>>>>         log.debug("HTTP GET for : " +
>>>> variant.getMediaType().getName());
>>>> ...
>>>>
>>>>
>>>>
>>>>
>>>> Thierry Boileau wrote:
>>>>   
>>>>       
>>>>> Hello Andrzej,
>>>>>
>>>>> I wonder if the source cause if your issue is out there.
>>>>> Could you tell us how are built your resources? How do you send the 
>>>>> request using jquery?
>>>>>
>>>>> Best regards,
>>>>> Thierry Boileau
>>>>>
>>>>>     
>>>>>         
>>>>>> Our Restlet resource server APPLICATION_JSON and APPLICATION_XML. A
>>>>>> JQuery
>>>>>> client, sets the Accept Type to "*/*, application/xml". So the
>>>>>> Restlet
>>>>>> negotiates that APPLICATION_JSON should be returned as expected.
>>>>>> However,
>>>>>> we
>>>>>> want APPLICATION_XML to be served. The problem is that we are unable
>>>>>> to
>>>>>> remove the "*/*" as the first Accept type in JQuery. JQuery seems to
>>>>>> tack
>>>>>> on
>>>>>> the "*/*" as an Accept Type to every request we send.
>>>>>>
>>>>>> Is there an elegant way in Restlet to filter the "*/*" values, e.g.
>>>>>> ALL
>>>>>> or
>>>>>> APPLICATION_ALL? We can certainly get the Accept Headers in Restlet
>>>>>> and
>>>>>> re-arrange the Accept list ourselves to "override" the Restlet
>>>>>> negotiation.
>>>>>> We are thinking of filtering, after Restlet negotiation, based on the
>>>>>> User-Agent header for this particular JQuery client, so as not to
>>>>>> "break"
>>>>>> the Restlet behaviour for other clients (which is what we expect.)
>>>>>>
>>>>>>       
>>>>>>           
>>>>> ------------------------------------------------------
>>>>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2430776
>>>>>
>>>>>
>>>>>     
>>>>>         
>>>>       
>>> ------------------------------------------------------
>>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2430802
>>>
>>>
>>>     
>>
>>
> 
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2430822
> 
> 

-- 
View this message in context: 
http://n2.nabble.com/MIME-Accept-Type-filter-tp4173789p4178248.html
Sent from the Restlet Discuss mailing list archive at Nabble.com.

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2430945

Reply via email to