4

i have implemented rest webservices using Jersey, and whenever some exception occur on the server side, the client gets a generic HTTP 500 Internal Server Error, with no more info of the real exception. I found that people usually catch any exception on the server side, then throws a WebApplicationException, but even this way the client keeps getting the generic HTTP 500 Internal Server Error.

This is my webservice:

@PUT @Produces(MediaType.APPLICATION_XML) @Consumes(MediaType.APPLICATION_XML) @Path("/transmitir") public WrapperTransmissaoRetorno receber(WrapperTransmissao wrapperRecepcao) { WrapperTransmissaoRetorno retorno = new WrapperTransmissaoRetorno(); retorno.setCodigoMaster(new Random().nextInt()); retorno.setDataRetorno(new Date()); if(true){ throw new WebApplicationException("Este pau eh bem graudo"); } return retorno; } 

This is the code that calls the client:

try { WsTransmissaoCliente client = new WsTransmissaoCliente(); WrapperTransmissao wrapperRecepcao = new WrapperTransmissao(); Transferencia transferencia = new Transferencia(); transferencia.setCodigoTabela(23); transferencia.setCodigoTransferencia(56); transferencia.setDataRetorno(new Date()); transferencia.setDataTransmissao(new Date(System.currentTimeMillis()+3000000)); transferencia.setNomeTabela("CUPOM"); transferencia.setTipoOperacao(TipoOperacao.UPDATE); wrapperRecepcao.setTransferencia(transferencia); Jumento jumento = new Jumento(); jumento.setIdade(24); jumento.setNome("José"); wrapperRecepcao.setObjeto(jumento); // Cabrito cabrito = new Cabrito(); // cabrito.setAltura(56); // cabrito.setPeso(120.0); // wrapperRecepcao.setObjeto(cabrito); WrapperTransmissaoRetorno retorno = client.transmitir(wrapperRecepcao); System.out.println("Retorno do WS: "+retorno); } catch (Exception e) { WebApplicationException exx = (WebApplicationException) e; exx.printStackTrace(); } 

How to avoid this and get the real exception? Or at least the message?

UPDATE Here is the object i am sending as a response:

package br.atualy.integracaocheckout.wrappers; import java.util.Date; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class WrapperTransmissaoRetorno { private Date dataRetorno; private Integer codigoMaster; public Date getDataRetorno() { return dataRetorno; } public void setDataRetorno(Date dataRetorno) { this.dataRetorno = dataRetorno; } public Integer getCodigoMaster() { return codigoMaster; } public void setCodigoMaster(Integer codigoMaster) { this.codigoMaster = codigoMaster; } @Override public String toString() { return "WrapperRecepcaoRetorno{" + "dataRetorno=" + dataRetorno + ", codigoMaster=" + codigoMaster + '}'; } } 

UPDATE 2 And here is the client:

import br.atualy.integracaocheckout.wrappers.WrapperTransmissao; import br.atualy.integracaocheckout.wrappers.WrapperTransmissaoRetorno; import javax.ws.rs.ClientErrorException; import javax.ws.rs.client.Client; import javax.ws.rs.client.WebTarget; public class WsTransmissaoCliente { private final WebTarget webTarget; private final Client client; private static final String BASE_URI = "http://localhost:8080/IntegracaoCheckout/webresources"; public WsTransmissaoCliente() { client = javax.ws.rs.client.ClientBuilder.newClient(); webTarget = client.target(BASE_URI).path("transmissao"); } // public String receber() throws ClientErrorException { // WebTarget resource = webTarget; // resource = resource.path("receber"); // return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(String.class); // } public WrapperTransmissaoRetorno transmitir(WrapperTransmissao requestEntity) throws ClientErrorException { return webTarget.path("transmitir") .request(javax.ws.rs.core.MediaType.APPLICATION_XML) .put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_XML), WrapperTransmissaoRetorno.class); } public void close() { client.close(); } } 
5
  • please post the code of WrapperTransmissaoRetorno, is it annotated? don't you get any messagebody writer exception in tomcat? nothing about nothing? Commented May 20, 2014 at 19:02
  • I have put the Wrapper in the description, see my update on the question. Commented May 20, 2014 at 19:05
  • post code of WsTransmissaoCliente please.. Commented May 20, 2014 at 19:20
  • Please, look atthe update again Commented May 20, 2014 at 19:38
  • it should work, take a look at @azurefrog answer Commented May 20, 2014 at 19:39

4 Answers 4

4

If using jawax.ws.rs.core.Response object.

SERVER :: In case of exception/failure set it as :

// do stuff // here e.getMessage() can be custom failure message too response = Response.serverError().entity(e.getMessage()).build(); // return response object return response; 

CLIENT :: On the client side check following :

if(response != null && reponse.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) { String serverErrorMsg = response.readEntity(String.class); throw new Exception(serverErrorMsg); } 
Sign up to request clarification or add additional context in comments.

Comments

2

Generally it's better to declare your method as returning a Response object instead of a user-defined type, and set the data as the entity. Then if you want to indicate that an exception has happened, you can just pass that exception as the entity of the Response you are returning.

e.g.

@GET @Path("/foo") public Response getFoo() { try { // do stuff return Response.ok(someData).build(); } catch (Exception e) { return Response.serverError().entity(e).build(); } } 

You'll notice that this way you don't ever end up actually throwing an exception out of your method, but rather return an explicit 500 response with an exception as the entity. This way you can still throw exceptions out of your code, but they'll be handled nicely.

EDIT

I'm not sure what your client wrapper code is doing, but you can pass the expected response data type into your call with the normal REST client:

 Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://foo.com/foo"); String response = target.request().get(String.class); 

or you can also pull it out of the Response using the readEntity() method:

 Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://foo.com/foo"); Response response = target.request().get(); String entity = response.readEntity(String.class); 

It sounds like what you need to do is check the return code, and then parse the entity as a either a WrapperTransmissaoRetorno or a WebApplicationException depending on what code was returned:

 Response response = client.transmitir(wrapperRecepcao); if (response.getStatus() == Response.Status.OK.getStatusCode()) { // 200 WrapperTransmissaoRetorno retorno = response.readEntity(WrapperTransmissaoRetorno.class); // do stuff } else if (response.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) { // 500 WebApplicationException e = response.readEntity(WebApplicationException.class); // do stuff } // etc for other response codes 

6 Comments

Alright, but on the client if i try to get the Response Entity it returns neither the exception(when it occurs) nor the actual method return. It just returns me a HttpUrlConnector instance...
a part from this, error is on server side i guess, but maybe the part in client for the class WsTransmissaoCliente is doing something wrong
If you're seeing an entity of type HttpUrlConnector, you're seeing the raw response object, you need to parse it to get the type you really want. I've updated the answer with a couple ways to do that.
don't forget the in the put to specify the entity type.. WebTarget wt = c.target("http://localhost:8084/simple-service/webapi/myresource"); Response r = wt.path("test1").request().put(Entity.entity(w, MediaType.APPLICATION_XML)); Put the encoding you want for it, otherwise you may get as message body reader exception..
I have tried to return a Response again on the server, but now on the client when i try to read the entity with response.readEntity(WebApplicationException.class);, it says MessageBodyProviderNotFoundException - This is the same error that happens when there is no @XmlRootElement in the return or parameter class
|
1

Use response object in webapplication excemption. It should work.

From java docs:

WebApplicationException(String message) Construct a new instance with a blank message and default HTTP status code of 500.

Its a blank message. I haven't tried it myself. I guess this is the problem.

https://jersey.java.net/apidocs/2.6/jersey/javax/ws/rs/WebApplicationException.html

Comments

-1

Even after all the suggestions i could not manage to throw the exception to the client. So what i did was to put a String property inside my returning class, so when an exception occurs on the server side, this String will contain the exception message and i can get it on the client.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.