users@jersey.java.net

[Jersey] Re: Method dispatch based on MediaType

From: Joe Mocker <jmocker_at_Tremorvideo.com>
Date: Fri, 6 Nov 2015 16:30:13 +0000

While I don't have an answer to your question about determining the mim-type Jersey will pick for the response, My suspicion is that you are after the ability to create a single resource method can output to multiple formats (instead of a resource method per format).

If that is the case, I'd suggest you check out and implement a custom MessageBodyWriter writer or two. MessageBodyWriters give you the ability to separate serialization from your resource methods. You would implement two writers, one for JSON, another for XML, then your resource method could then be configured to include multiple mime types in the Produces annotation, and Jersey will select the appropriate MessageBodyWriter to use based on the request Accept header.

  --joe


From: Kevin Hale Boyes <kcboyes_at_gmail.com<mailto:kcboyes_at_gmail.com>>
Reply-To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Date: Thursday, November 5, 2015 at 7:56 AM
To: users <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Subject: [Jersey] Re: Method dispatch based on MediaType

I'm finally back to this after an unexpected delay.
First off, thanks Pavel for such a rapid response to my question!!
Second, this is absolutely what I was after.
I've now had to the time to verify that it does work in Jersey 1.19 as you've said.

Also, I'm able to get the 406 behaviour by defining only two methods. One @Produces JSON and the other XML.
When a request comes in for, say PDF, then it will get the 406 error.

I have a slightly related question after reading that unit test.
In the testReordered() unit test it will dispatch to the getListReordered() method.
If I send a request with "Accept: application/json" to such an endpoint (i.e., one that lists multiple mime types in the Produces annotation) is there any way to determine in the code what the response format will be? I know that jersey/jackson knows but is there any way for the application code to know?

Thanks again for your help,
Kevin.

On 2 November 2015 at 12:44, Pavel Bucek <pavel.bucek_at_oracle.com<mailto:pavel.bucek_at_oracle.com>> wrote:
Hi Kevin,

for the first part: you can use "quality" params in produces annotations, something like:


@Produces("application/json;qs=0.75")



(see https://github.com/jersey/jersey/blob/b7907e279010e7035a7a3e529993d22f77a21e08/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/server/ContentNegotiationTest.java ; this is taken from Jersey 2.x, but it should work in Jersey 1.x as well).

more formal definition can be found at:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9


The second one would be harder to do automatically, but you can always do @Produces("*/*, qs=0,1"), which will be matched when "application/pdf" is requested and can return Response.status(406).build() or something like that..

Hope it helps,
Pavel



On 02/11/15 11:29, Kevin Hale Boyes wrote:
I have a resource with a couple of "search" methods.
They can produce their output in either JSON or XML based on the request Accept header.

So, my methods basically look like this:


@GET
@Produces(MediaType.APPLICATION_JSON)
public Response searchReturningJSON(@Context HttpServletRequest request) {
    return performSearch(request, MediaType.APPLICATION_JSON);
}


@GET
@Produces(MediaType.APPLICATION_XML)
public Response searchReturningXML(@Context HttpServletRequest request) {
    return performSearch(request, MediaType.APPLICATION_XML);
}


I'm hoping someone can help my with two things that I don't know how to do.

I would like to have a default of JSON when the client gives */* for the Accept header.
I would also like to (continue to) return a 406 error if the client asks for something different, like application/pdf.

I'm using Jersey 1.19 in case it matters.

Thanks,
Kevin.