views:

813

answers:

1

Hi,

I'm using Jersey Client API in the following way :-

User user = webRsrc.accept(MediaType.APPLICATION_XML).post(User.class, usr);

So I'm expecting the response in object of User class which is a JAXB annotated class. However, at times I might also get an error xml and for that I've created a JAXB class ErrorResponse.

Now the problem is that if my request returns an object of ErrorResponse instead of User how can I handle that ?

I tried like this -

ClientResponse response=null;
try {

        response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);
        User usr = response.getEntity(User.class);    
    }catch(Exception exp)
    {
       ErrorResponse err = response.getEntity(ErrorResponse.class);    
    }

But when I try to use getEntity() in catch block, it throws following exception

[org.xml.sax.SAXParseException: Premature end of file.]
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:107)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:532)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:491) .....

Seems like after calling getEntity() once, the inputstream is exhausted.

+1  A: 

Hey netlogger!
I think you missed a point in the whole "REST way of thinking".
Short answer: yes, you can only call getEntity once. You need to check the returned HTTP status to know what entity you should get.

On the server side:

  1. When designing a REST API, one should always use appropriate status codes regarding the HTTP RFC.
  2. For that matter, please consider using the ExceptionMapper interface (here's an example with a "NotFoundException"

So, now your server returns either "HTTP status OK - 200" with a User object, or an error status with an error object.

On the client side:

You need to check the return status and adapt your behavior according to the API spec. here's a quick and dirty code sample:

ClientResponse response=null;

response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);

int status = response.getStatus();

if (Response.Status.OK.getStatusCode() == status) {

  // normal case, you receive your User object
  User usr = response.getEntity(User.class);

} else {

  ErrorResponse err = response.getEntity(ErrorResponse.class);
}

NB: depending on the status code returned, this error could be very different (thus needing very different behavior):

  • client error 40X: your client request is wrong
  • server error 500: an unexpected error occured on the server side
Brian Clozel
Yes you are right Brian m8, thanks :) Unfortunately the guys who designed the services that I'm accessing, seem to have not gone by these principles. But your info is gonna come in very handy whenever I'm gonna be designing my own services. Thanks again :)
netlogger