users@jersey.java.net

[Jersey] Re: JsonP without using JSONWithPadding?

From: John Lister <john.lister_at_kickstone.com>
Date: Tue, 22 Nov 2011 09:29:12 +0000

On 19:59, ed_at_anuff.com wrote:
> My web services I'm basically returning POJO's from my methods and I'm
> setting com.sun.jersey.api.json.POJOMappingFeature=true. Currently, to do
> JSONP, I had to do the following:
>
> 1) change the produces to:
>
> @Produces({ MediaType.APPLICATION_JSON, "application/javascript",
> "application/x-javascript", "text/ecmascript",
> "application/ecmascript", "text/jscript" })
>
> 2) change every method signature to include:
>
> @QueryParam("callback") @DefaultValue("callback") String callback
>
> 3) change every return type of every method to JSONWithPadding (from my own
> return type of ApiResponse).
>
> 4) wrap the return type at the end of every method:
>
> return new JSONWithPadding(response, callback);
>
> I may be missing something and there might be an easier way, but it would be
> nice of all of that boilerplate wasn't necessary. I did try to write my own
> provider based on the JSONWithPaddingProvider but didn't get very far.
I ended up creating a provider that extends JacksonJsonProvider mapped
to returning json. In the provider I inject a HttpServletRequest object
and override the getSize and writeTo methods to check if a parameter by
the name of callback has been passed. If so in getSize I add the size of
the callback string +2 for brackets to the size of the actual json
(obtained by calling super.getSize) and return that. in writeTo, if the
callback parameter has been set, I write it out followed by an opening
bracket, then call super.writeTo before writing a closing bracket.

This works for every json response and returns jsonp if a callback param
is passed without any boilerplate. If you want the code, let me know.

I started using the jackson json encoder early on in jerseys lifetime
however I think it is now the standard encoded in jersey, if not modify
to suit whichever encoder you have.

John