users@jersey.java.net

Re: [Jersey] Custom media types with JAXB-JSON providers?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 25 Nov 2008 10:54:37 +0100

On Nov 24, 2008, at 10:21 PM, Craig McClanahan wrote:

> Paul Sandoz wrote:
>> Hi Craig,
>>
>> I think we might be able to do something "magical" but it requires
>> a little magic fairy dust to banish a bug.
>>
>> The reason being is the JAXB XML providers are a little too greedy
>> and they should only support application/*+xml in addition to text/
>> xml and application/xml.
>>
>> Under these conditions we should be able to support application/*
>> +json and application/json.
>>
>> This is possible because the isWriteable and isReadable methods
>> also take the media type and the sub part can be checked.
>>
>> Could you log an issue?
>>
> https://jersey.dev.java.net/issues/show_bug.cgi?id=149
>
> I will also do some looking into possible solutions along the lines
> of what you suggested above.


Some clues on what can be done:

- The com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider could a
method isMediaTypeSupported(MediaType m),
    which by default always returns true.

- The abstract classes specific to JAXB types can call
isMediaTypeSupported in the isReadable/isWritable methods.

- The concrete JAXB provider supporting "*/*" for @Produce/_at_Consume
can provide a specialization of
   isMediaTypeSupported and configuration information could be taken
into account in this respect.

Paul.

> I'd really like "x-foo/x-bar+json" as well as "application/*
> +json" ... but that should probably be a configurable option because
> it could also be overly greedy.
>
> Craig
>> Paul.
>>
>> On Nov 24, 2008, at 9:26 PM, Craig McClanahan wrote:
>>
>>> I'm experimenting with defining my own media types (in the
>>> examples below, "x-foo/x-bar" is used), to give clients of my JAX-
>>> RS service a bit more information than generic content types like
>>> "application/json" or "application/xml". But, I still want to
>>> support both XML and JSON representation of the resources, because
>>> some clients (or the developers of some clients :-) might prefer
>>> one format over the other.
>>>
>>> A convention that I've seen in the wild is to add "+xml" or (by
>>> extension) "+json" to the media type, to communicate both the
>>> actual media type and the desired representation syntax together.
>>> Thus, I might have a resource method like this:
>>>
>>> @GET
>>> @Produces{{"x-foo/x-bar+xml", "x-foo/x-bar+json"})
>>> public Response getResults(...) { ... }
>>>
>>> where the response entity is going to be a JAXBElement ... in
>>> theory, that way, I get either XML or JSON serialization with no
>>> extra effort.
>>>
>>> The problem I'm seeing, though, comes from doing a request that
>>> includes:
>>>
>>> Accept: x-foo/x-bar+json
>>>
>>> The response I get claims "x-foo/x-bar+json" as its Content-Type,
>>> but in reality it's XML. Hmm.
>>>
>>> Digging into the Jersey code a bit, it appears that the root cause
>>> of this is that Jersey's JSONJAXBElementProvider class (the one
>>> that does the JSON serialization for JAXB objects) declares that
>>> it consumes and produces only "application/json", so naturally it
>>> doesn't get picked by Jersey to handle this kind of entity.
>>> Instead, Jersey falls back to the usual JAXB processing, which (of
>>> course) serializes as XML.
>>>
>>> What I'd really like is an easy way to configure something like "*/
>>> *+json" to use the JSON provider, but that doesn't appear to be a
>>> legal pattern. Failing that, I'm looking for other ways to
>>> accomplish this goal, including:
>>>
>>> (1) Subclass Jersey's JSONJAXBElementProvider and use @Produces
>>> and @Consumes
>>> annotations on it for all my "x-xxx/x-yyy+json" media types.
>>>
>>> (2) Avoid a direct Jersey implementation dependency by cut-n-
>>> pasting the base class
>>> into my own application, and adding all the appropriate
>>> annotations directly.
>>>
>>> (3) Some magical technique to configure this that I don't know
>>> about already.
>>>
>>> I'm kinda hoping for an early Christmas present of someone
>>> pointing out a type (3) solution :-). But, without that, is my
>>> analysis of what's going on correct? Any other approaches to
>>> suggest?
>>>
>>> Craig
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>