users@jersey.java.net

Re: [Jersey] GET method consuming JSON

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 12 Apr 2010 11:01:06 +0200

Hi Franz,

Jersey has a plug in mechanism for plugging in customer support for
parameters, StringReaderProvider (in fact all the default mechanisms
are supported using StringReaderProvider):

   https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/spi/StringReaderProvider.html

Jersey already supports XML-based parameters using JAXB. The problem
here is that when using XML or JSON for values in the URI then there
is no information as to the syntax of the string.

You can implement your own StringReaderProvider that encapsulates the
"service layer logic" you have defined in the method, but i would
recommend requiring that such JAXB-related parameters be annotated,
e.g. @Json, way the StringReaderProvider can ignore parameters that
are not marked appropriately. (Unfortunately we cannot reuse @Consumes
because it is not declarable on method parameters).

   @Path("/myservice")
   // Use GET because jQuery.ajax sends OPTIONS instead of POST when
using POST
   @GET
   @Produces(MediaType.APPLICATION_JSON)
   public MyResponse action(@QueryParam("myRequest") @Json MyRequest
r) {
   }

In fact if you log an issue we should be able to add support for for
XML and JSON-based parameters.

Paul.



On Apr 9, 2010, at 7:46 PM, Franz Wong wrote:

> I have changed the action method of MyService class to the following
> and it works. I don't know whether it is the exact way you
> suggested. For me, it seems weird to include too much service layer
> logic in that class which I thought that belongs to business layer.
>
> Thanks Marc :)
>
> @Path("/myservice")
> // Use GET because jQuery.ajax sends OPTIONS instead of POST when
> using POST
> @GET
> @Consumes(MediaType.APPLICATION_JSON)
> @Produces(MediaType.APPLICATION_JSON)
> public MyResponse action(@Context Providers providers, @Context
> HttpHeaders httpHeaders, @QueryParam("myRequest") String
> myRequestString) {
> MessageBodyReader<QueueRequest> msgBodyReader =
> providers.getMessageBodyReader(MyRequest.class, null, null,
> MediaType.APPLICATION_JSON_TYPE);
> InputStream inputStream = new
> ByteArrayInputStream(myRequestString.getBytes());
> MyRequest myRequest = null;
> try {
> myRequest = msgBodyReader.readFrom(MyRequest.class, null,
> null, MediaType.APPLICATION_JSON_TYPE,
> httpHeaders.getRequestHeaders(), inputStream);
> } catch (Exception e) {
> e.printStackTrace();
> }
> return new MyResponse(); // currently no logic
> }
>
> On Sat, Apr 10, 2010 at 12:48 AM, Marc Hadley
> <marc.hadley_at_oracle.com> wrote:
> On Apr 9, 2010, at 11:15 AM, Franz Wong wrote:
>
> > Thanks for your reply.
> >
> > Does that mean I need to parse the JSON myself if I create a
> static valueOf method? As a rough guess, I should be able to reuse
> some code which jersey uses to parse JSON for POST. Am I correct?
> >
> You can lookup the default MessageBodyReader using an injected
> Providers:
>
> https://jsr311.dev.java.net/nonav/releases/1.0/javax/ws/rs/ext/Providers.html
>
> You can then use the default reader to deserialize the JSON.
>
> Marc.
>
> >
> > On Fri, Apr 9, 2010 at 8:25 PM, Marc Hadley
> <marc.hadley_at_oracle.com> wrote:
> > @Consumes only applies to the request message body so it isn't
> applicable to GET since that doesn't allow one. Example 1 looks
> right to me, to extract the JSON you would replace the "MyRequest
> myRequest" parameter in the action method with
> "@QueryParam("myRequest") SomeType myRequest".
> >
> > SomeType can be any type that has a String constructor or a static
> valueOf or fromString method that takes a single String argument.
> See the javadoc for @QueryParam for full details.
> >
> > Marc.
> >
> > On Apr 9, 2010, at 6:11 AM, Franz Wong wrote:
> > >
> > > I would like to write a restful service which use @GET and
> @Consumes(MediaType.APPLICATION_JSON). I can only google example for
> @POST. I don't know whether I need to use @QueryParam for my
> parameters for GET method. If yes, how does the request line of the
> HTTP request become?
> > >
> > > Thanks.
> > > Franz
> > >
> > > (In real environment, the request line is url encodeded)
> > >
> > > 1. GET /myservice?myRequest={"actionList":
> ["action1","action2"],"triggerName":"triggerName1"} HTTP/1.1
> > > 2. GET /myservice?{"myRequest":{"actionList":
> ["action1","action2"],"triggerName":"triggerName1"}} HTTP/1.1
> > >
> > > Here is my code.
> > >
> > > @Singleton
> > > @Path("/")
> > > public class MyService {
> > > @Path("/myservice")
> > > // Use GET because jQuery.ajax sends OPTIONS instead of POST
> when using POST
> > > @GET
> > > @Consumes(MediaType.APPLICATION_JSON)
> > > @Produces(MediaType.APPLICATION_JSON)
> > > public MyResponse action(MyRequest myRequest) {
> > > return new MyResponse(); // currently no logic
> > > }
> > > }
> > >
> > > @XmlRootElement
> > > public class MyRequest {
> > > private List<String> actionList = new ArrayList<String>();
> > > private String triggerName;
> > >
> > > ... getters and setters
> > > }
> > >
> > > @XmlRootElement
> > > public class MyResponse {
> > > private String result;
> > >
> > > ... getters and setters
> > > }
> > >
> > > For reference, here is my client (in javascript) calling the
> service.
> > >
> > > $.ajax({
> > > type: "GET",
> > > url: "http://localhost:8080/myservice",
> > > dataType: "json",
> > > data: "{" +
> > > "\"myRequest\" : {" +
> > > "\"actionList\" : [\"action1\",\"action2\"]," +
> > > "\"triggerName\" : \"triggerName1\"" +
> > > "}" +
> > > "}",
> > > contentType: "application/json; charset=UTF-8",
> > > success: function(msg){
> > > alert("ok");
> > > },
> > > error: function(xhr, msg) { alert(msg + '\n' +
> xhr.responseText); }
> > > });
> >
> >
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>