Here's my use case:
I'm submitting a conditional GET (using If-None-Match, although I don't think
that's relevant) request that also specifies a media type in the Accept header
that doesn't match any of the media types supported by the target resource
(i.e. it doesn't correspond to any of the media type extensions specified in
the @Get annotation).
When I don't specify a condition, I get the expected 406 response. However,
when I specify the condition, the code goes through
ServerResource.doConditionalHandle() instead of doNegotiatedHandle().
OK, now, please bear with me for a bit of code narrative :-)
doConditionalHandle() checks isNegotatiated() and invokes
doGetInfo(getPreferredVariant(getVariants(Method.GET)).
getPreferredVariant() returns null, as it should in this case, so we drop into
the other doGetInfo(), that is, the one with no args. From there, we go into
doHandle, because annotationInfo is non-null. doHandle invokes the
@Get-annotated method, which returns a non-null resultObject, which doHandle
passes to toRepresentation(resultObject, variant), with variant=null.
If you're still with me, here's where things start to go wrong...
Resource.toRepresentation() calls ConverterService.toRepresentation(), which
tries to select the best ConverterHelper. As it happens, I'm using both the
GwtConverter and JacksonConverter. For reasons I don't understand, both of
those converters return 0.5 from their score() methods when the target variant
is null (GwtConverter does this if the source object is Serializable,
JacksonConverter does it if the source object is not already an instanceof
JacksonRepresentation<?>). This doesn't seem right to me; if the target is
null, it seems like those converter classes should return -1.0 from their
score() methods.
But, as things stand, the GwtConverter wins (I guess it was first in some
ordering), and thus instead of returning null, toRepresentation returns an
ObjectRepresentation that it got from GwtConverter.
>From here, we traverse back up the stack several levels to
>ServerResource.doConditionalHandle() again, which gets the
>ObjectRepresentation back from doGetInfo(). It does the following:
if ((Method.GET.equals(getMethod()) || Method.HEAD
.equals(getMethod()))
&& resultInfo instanceof Representation) {
result = (Representation) resultInfo;
and since the if() statement is true, it proceeds to return the result, and the
client gets back the "application/x-java-serialized-object+gwt" representation
instead of a 406.
SO... is this a bug, or am I doing something wrong? Should those converters
return -1.0 from their score() methods? Or should doConditionalHandle()
consider the possibility that despite getting a non-null Representation back
from doGetInfo(), it needs to do content negotation anyway?
Thanks in advance for any advice.
-Andy
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2947774