users@jersey.java.net

Re: [Jersey] _at_Produces on ContextResolver impls <was> Re: [Jersey] Re: Adding @Provider via META-INF/services, injecting @Context Providers?

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Wed, 29 Apr 2009 11:24:33 -0400

On Apr 29, 2009, at 3:43 AM, Paul Sandoz wrote:

> Hi Tatu,
>
> _providers.getContextResolver(ObjectMapper.class, null) will match
> say:
>
> @Provider MyResolver implements ContextResolver<ObjectMapper> { ... }
> @Provider("*/*") MyResolver implements
> ContextResolver<ObjectMapper> { ... }
>
Assuming @Provider("*/*") is shorthand for @Provider @Produces("*/*")

> _providers.getContextResolver(ObjectMapper.class,
> MedaType.APPLICATION_JSON_TYPE) will match say:
>
> @Provider("application/json") MyResolver implements
> ContextResolver<ObjectMapper> { ... }
>
> but will not match:
>
> @Provider("*/*") MyResolver implements
> ContextResolver<ObjectMapper> { ... }
>
I think it should since application/json is compatible with */*.

> The spec is a little vague on the matching process:
>
> https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/Providers.html
> #getContextResolver(java.lang.Class,%20javax.ws.rs.core.MediaType)
>
> I think the issue may be that Jersey has implemented the
> Providers.getContextResolver too strictly. So if i have the
> following providers:
>
> @Provider("*/*") MyResolver1 implements
> ContextResolver<ObjectMapper> { ... }
> @Provider("application/json") MyResolver2 implements
> ContextResolver<ObjectMapper> { ... }
>
> I think a call to:
>
> _providers.getContextResolver(ObjectMapper.class,
> MedaType.APPLICATION_JSON_TYPE)
>
> should return a non-null value that encapsulates both providers in
> order of MyResolver1 and MyResolver2.
>
> Is that your expectation? i need to double check with Marc as well.
>
Right. It should return a proxy that first calls MyResolver2 and if
that returns null then calls MyResolver1. Resolvers are ordered so the
closest matching @Produces is sorted first:

https://jsr311.dev.java.net/nonav/releases/1.0/javax/ws/rs/ext/Providers.html
#getContextResolver(java.lang.Class,%20javax.ws.rs.core.MediaType)

Marc.

> Currently it is left up to the developer to explicitly call as
> follows:
>
> MediaType m = ...
> r = _providers.getContextResolver(ObjectMapper.class, m);
> om = (r != null) ? r.getContext(type) : null;
> if (om == null) {
> r = _providers.getContextResolver(ObjectMapper.class, new
> MediaType(m.getType(), "*"));
> om = (r != null) ? r.getContext(type) : null;
> }
> if (om == null) {
> r = _providers.getContextResolver(ObjectMapper.class, new
> MediaType("*", "*"));
> om = (r != null) ? r.getContext(type) : null;
> }
>
> Paul.
>
> On Apr 28, 2009, at 7:02 PM, Tatu Saloranta wrote:
>
>> On Tue, Apr 28, 2009 at 9:50 AM, Tatu Saloranta
>> <tsaloranta_at_gmail.com> wrote:
>> ...
>>> But the remaining problem (if it is any -- may be my
>>>
>>> ContextResolver<ObjectMapper> resolver =
>>> _providers.getContextResolver(ObjectMapper.class, mediaType);
>>>
>>> returns null, whereas:
>>>
>>> resolver = _providers.getContextResolver(ObjectMapper.class, null);
>>>
>>> does not.
>>>
>>> I wonder if I need to add both @Consumes and @Produces annotations
>>> in
>>
>> Ok found it: javadocs state it's @Produces that counts.
>>
>> However:
>>
>>> ContextResolver<ObjectMapper> implementation?
>>> Or do these have any effect? If not, what determines MediaType
>>> matching rules?
>>> I can also just try registering ObjectMapper as singleton directly:
>>> that should work reliably.
>>
>> I can not make this match anything but exact media type
>> ("application/json"), either via provider or direct instance;
>> neither @Produces (which defaults to "*/*") nor explicit "*/*" seem
>> to
>> work. @Produces("application/json") does.
>>
>> So I wonder if there might be a problem in media type matching code?
>> This is in jersey 1.0.3.
>>
>> In the meantime I can just have the fallback call to pass null Media
>> Type, since that does work ok.
>>
>> -+ Tatu +-
>>
>> ---------------------------------------------------------------------
>> 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
>