users@jersey.java.net

[Jersey] Seamless JSONP-Support for Jersey 1.x Server

From: <spam2014_at_meeque.de>
Date: Mon, 20 Jan 2014 00:10:00 +0100

Hello Jersey Community,


Just wanted to throw some code out there that I wrote last week. My
motivation was to extend Jersey 1.x to handle JSONP more conveniently.
As I'm writing this now, I realize that the 2.5.x versions of Jersey may
already have a similar or better solution. However, we're still using
Jersey 1.3 in the related project, so maybe that helps other people who
are still stuck with older versions...


Jersey 1.x does have basic support for JSONP through the
JSONWithPaddingProvider. However, that requires the use of type
JSONWithPadding as the return value of the application's service
methods. Thus it seems to put a lot of burden on the application
developer.

In particular, in our project we wanted to make our services support
XML, JSON, and JSONP formats. And we wanted to use JAXB for marshalling,
without the need of format-specific tweaks. I.e. application-code should
not need to deal with JSONWithPadding objects.


Turns out that extending Jersey 1.x for that purpose was not overly
difficult. I just had to write the two Provider classes that are
attached to this e-mail. These providers are meant as alternatives: one
supports dynamic callback names, the other one doesn't. (See JavaDocs
for more info.)

Once I registered an instance of one of these Providers with Jersey (in
our case: simply by declaring an appropriate Spring bean) everything
worked as expected. Our pre-existing service implementations now support
JSONP, too. The only required tweak to application code was to add
another MediaType to the @Produces annotation. See the following usage
example:


@Path( "/service/{foo}" )
@Produces( {
  MediaType.APPLICATION_XML,
  MediaType.APPLICATION_JSON,
  "application/javascript" // for JSONP support
} )
public class ExampleService
{

  @GET @Path( "/operation1" )
  public Operation1Result operation1(
      @PathParam("foo") String foo,
      @QueryParam("paramA") String paramA )
  {
    // ...
  }

  @GET @Path("/operation2")
  public Operation2Result operation2(
      @PathParam("foo") String foo )
  {
    // ...
  }

}


Note that the attached source-files are merely sketches. I'd still have
to clean up package names, reduce some dependencies, etc. So if anyone
is interested in that solution, please let me know, and I'll do the
extra effort.


Also, I'm wondering how good the JSONP support in Jersey 2.5.x really
is? I found the @JSONP annotation in the JavaDocs, which seems to
support similar configuration as my own Provider classes. So I assume
that users of Jersey 2.5.x do have rather convenient JSONP support
out-of-the-box then? I hope I'll get around to try an upgrade any time
soon...


Best Regards,
Michael Riedel


[Note: I'm re-posting this message. First time I tried, the list
rejected it, since I was not registered yet. Please excuse, if it shows
up twice after all!]