custom Content-Type and jersey

1,742 views
Skip to first unread message

Sam Perman

unread,
May 15, 2012, 11:58:10 AM5/15/12
to dropwiz...@googlegroups.com
Hello

We're planning on returning different content type headers for different resources (something like "application/x-mytype+json") and I had a question about configuring jersey.

The only way i have gotten this to work is to register my own subclass of JacksonMessageBodyProvider.  Is it possible to programmatically change the supported content types so I don't end up creating something like this:

    @Produces(value={"application/x-mytype1+json", "application/x-mytype2+json"})
    @Consumes(value={"application/x-mytype1+json", "application/x-mytype2+json"})
    public class MyJacksonMessageBodyProvider extends JacksonMessageBodyProvider {
        public MyJacksonMessageBodyProvider(Json json) {
            super(json);
        }
    }

It feels like a limitation of jersey but I'm hoping I'm just missing something.

thanks for any suggestions
sam

Ryan Kennedy

unread,
May 15, 2012, 12:57:17 PM5/15/12
to dropwiz...@googlegroups.com
You can wildcard the content type in the provider. I did this a while back (and then foolishly lost the code) to make a provider that would handle vendor MIME types. It wild carded application/vnd.*+json, extending the JSON provider like you have. See if that works…then you won't have to add all of your types to your provider class.

-- 
Ryan Kennedy

Sam Perman

unread,
May 15, 2012, 2:23:38 PM5/15/12
to dropwiz...@googlegroups.com
Thanks for the suggestion... I've tried it, but it's not working if I put the '*' anywhere in the middle... if I use "application/*" it works but I was hoping to constrain it a little more than that.

sam

Ryan Kennedy

unread,
May 15, 2012, 2:24:33 PM5/15/12
to dropwiz...@googlegroups.com
I'll see if I can resurrect my code tonight. It works…somehow.

-- 
Ryan Kennedy

Sam Perman

unread,
May 15, 2012, 2:29:03 PM5/15/12
to dropwiz...@googlegroups.com
Great. Thanks for the help :)

Christopher Elkins

unread,
May 15, 2012, 3:03:11 PM5/15/12
to dropwiz...@googlegroups.com
I don't think that's a Jersey limitation but rather baked into the JAX-RS spec (4.3.1):

'When choosing a context provider an implementation sorts the available providers according to the media types they declare support for. Sorting of media types follows the general rule: x/y < x/* < */*, i.e. a provider that explicitly lists a media type is sorted before a provider that lists */*.'

Have you looked at how the jersey-json module supports wildcards? It simply handles any media type and filters on isReadable/isWritable. Dropwizard could do something similar (though with unknown performance impact), e.g.,

@Provider
@Produces("application/*")
@Consumes("application/*")
public class JacksonMessageBodyProvider implements MessageBodyReader<Object>,
                                                   MessageBodyWriter<Object> {
    ...
    @Override
    public boolean isWriteable(Class<?> type,
                               Type genericType,
                               Annotation[] annotations,
                               MediaType mediaType) {
        return json.canSerialize(type) &&
            (mediaType.equals(MediaType.APPLICATION_JSON_TYPE) ||
             mediaType.getSubtype().endsWith("+json"));
    }
    ...

-- 
Christopher Elkins

Sam Perman

unread,
May 15, 2012, 5:30:14 PM5/15/12
to dropwiz...@googlegroups.com, dropwiz...@googlegroups.com
What I was originally looking for, before we started looking at wildcards, was to programmatically add content types to the provider rather than having to rely on annotations. That's what I was considering a jersey limitation. Is something like that possible?

thanks
sam


Tatu Saloranta

unread,
May 15, 2012, 7:56:25 PM5/15/12
to dropwiz...@googlegroups.com
On Tue, May 15, 2012 at 2:30 PM, Sam Perman <s...@permans.com> wrote:
> What I was originally looking for, before we started looking at wildcards,
> was to programmatically add content types to the provider rather than having
> to rely on annotations. That's what I was considering a jersey limitation.
> Is something like that possible?

I think choice is between using full custom logic -- meaning, take
InputStream, return StreamingOutput, figure out what to use for
conversion yourself -- or use annotations to let JAX-RS impl find
MessageBodyReader/-Writers dynamically.

-+ Tatu +-

Ryan Kennedy

unread,
May 16, 2012, 1:06:25 AM5/16/12
to dropwiz...@googlegroups.com
Yeah, this is exactly what I ended up doing (finally resuscitated the code). Wildcard the subtype and then dig deeper in the is[Readable|Writeable] method…


Then add the appropriate annotations to your resource…

@Produces("application/vnd.user-v1+json")
@Consumes("application/vnd.user-v1+json")

-- 
Ryan Kennedy

Sam Perman

unread,
May 17, 2012, 9:01:04 AM5/17/12
to dropwiz...@googlegroups.com
Thanks for the link. I ended up just explicitly listing the supported content types for now but will likely go with your approach if that set starts to grow. Things are working great for responses from my resource. Now I'm struggling with posting new resources. It appears that @Consumes doesn't consider parameters when choosing the correct method on my resource.  For example, if my resource defines:

    @POST
    @Consumes("application/x.mytype+json; type=foo")
    public Response createFoo(Foo foo) {
        ....
    }

    @POST
    @Consumes("application/x.mytype+json; type=bar")
    public Response createBar(Bar bar) {
        ....
    }

I get an error that these two methods conflict with each other. Are the parameters of the content type ignored when delegating?

thanks
sam

Ryan Kennedy

unread,
May 17, 2012, 12:17:38 PM5/17/12
to dropwiz...@googlegroups.com
I'm not sure what the internals of Jersey are up to there or what the spec says should happen in that situation. My guess is that the additional header information is being ignored. Does the @Consumes annotation even honor anything after the semicolon?

-- 
Ryan Kennedy

Tatu Saloranta

unread,
May 17, 2012, 2:02:48 PM5/17/12
to dropwiz...@googlegroups.com
This is a question for Jersey mailing lists for sure, but I would be
surprised if those parameters were used. It is difficult enough to
cover various permutations already. So it's probably something where
custom logic would make sense, getting difficult to do just using
annotations.

-+ Tatu +-

Sam Perman

unread,
May 17, 2012, 4:14:29 PM5/17/12
to dropwiz...@googlegroups.com
Thanks. I sent a message to the jersey mailing list. 

sam
Reply all
Reply to author
Forward
0 new messages