users@jersey.java.net

Re: [Jersey] Setting Response location, code, etc..

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 19 Jun 2008 08:47:13 +0200

Hi Kevin,

On Jun 19, 2008, at 4:30 AM, Kevin Duffey wrote:

> Hey all,
>
> We're starting to get a bit further with our project now. Actually
> got the RESTful web app deployed, and taking some calls.
>
> I am confused on a few things tho. Is there a good doc that
> explains all the details of Jersey, including handling requests,
> setting response codes, headers, body, etc?
>

Currently we are lacking such documentation. A good source of
knowledge is the Jersey examples and the 311 JavaDoc, in addition to
asking questions on this list :-)

See the following JavaDoc for returning meta-data in addition to a
body (entity):

https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/core/
Response.ResponseBuilder.html
https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/core/
Response.html



> That said, I am using the NetBeans Jersey plugin, created a
> resource, my code looks something like:
>
>
> @Path("test")
> public class TestResource {
>
> @Context
> private UriInfo context;
>
> public TestResource() {
> }
>
> @GET
> @ProduceMime("application/xml")
> public String getXml() {
> return "test";
> }
>
> @POST
> @ConsumeMime("application/xml")
> public void postXml(String content) {
> // do something that creates something...
>
> // if all works, set status to 201, and set Location header
> to URL
>
> // if fail, set appropriate Status code.
>
> // HOW DO I SET RESPONSE CODE, BODY, LOCATION, HEADER INFO
> HERE?
> }
> }
>
>
> So in the above, I am sending in some XML as the content object to
> postXml. I do something with that XML, create something, etc.
> However, the method that the wizard creates does not set a return
> value. Where as HttpServeltResponse returns a response object that
> you can set headers on, etc... there seems to be no way after the
> call is made for me to indicate the response code, body (if I want
> to return one), and the Location header to return the proper URL to
> reference the created resource.
>

See Response.created:

https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/core/
Response.html#created(java.net.URI)


> Same question applies to the GET method. I want to return a chunk
> of XML, or JSON maybe as part of the response Body, along with
> status code, etc. How do I manipulate the response that goes back.
> Looking at the UriInfo context variable doesnt appear to offer any
> methods or objects I can use to set response info.
>
> Is it ok to do something like
>
> @POST
> @ConsumeMime("application/xml")
> @ProduceMime("text/html")
> public String someMethod(String contents){}
>
> Such that I can handle xml input but return, html (or maybe json)?
> If so, to handle say xml, json or url-encoded form data in one
> call, and return json or xml back, how would I figure out the
> format coming in,

The media types for the set of incoming information is specified by
the @ConsumeMime. You can have the following if you wish:

   @POST
   @ConsumeMime("application/json") public String postConsumeJSon()
{ ... }

   @POST
   @ConsumeMime("application/xml") public String postConsumeXML()
{ ... }

or you can have it as one method:

   @POST
   @ConsumeMime({"application/json","application/xml"}) public String
consume() { ... }

If you need to know what the content type is for the above case then
use the HttpHeaders class:

https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/core/
HttpHeaders.html


> and how do I specify the return format (again, how do I manipulate
> the response object so the Content-Type header going back is set
> based on the body going back).
>

The @ProduceMime in your example specifies the media type for the
Content-Type. Such a method will only get invoked if one or more of
the media types in the produce mime is acceptable to the client.

If you need to know the media type that is acceptable you can use:

https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/core/
HttpHeaders.html#getAcceptableMediaTypes()

Again you can have separate methods if you like for the @ProduceMime.
Thus if you like you don't have to do the comparison logic yourself
and you can let Jersey do it by dispatching to the appropriate method.

A different type of case is when using say JAXB:

   @POST
   @ConsumeMime({"application/json","application/xml"})
   @ProduceMime({"application/json","application/xml"})
   public JAXBOutBean consume(JAXBInBean o) { ... }

You don't need to know what the content-type of the request is nor
what is acceptable as the content-type of the response. This is
because the Jersey JAXB support knows how to support XML or JSON
formats. This is using something called MessageBodyReader and
MessageBodyWriter:

https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/ext/
MessageBodyReader.html
https://jsr311.dev.java.net/nonav/releases/0.8/javax/ws/rs/ext/
MessageBodyWriter.html

See the EntityProvider example distributed with Jersey for more details.

Hope this helps,
Paul.