users@jersey.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 29 Apr 2009 09:43:11 +0200

Hi Tatu,

_providers.getContextResolver(ObjectMapper.class, null) will match say:

   @Provider MyResolver implements ContextResolver<ObjectMapper> { ... }
   @Provider("*/*") MyResolver implements
ContextResolver<ObjectMapper> { ... }

_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> { ... }

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.

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
>