Friday, July 20, 2012

Jersey Exception Handling

Jersey offers centralized Exception handling with "ExceptionMappers". This means you can allow Exceptions to be thrown up to the framework and then you can define how to handle them. It also means you are able to "catch" and handle exceptions that occur before and after the code that you write is being run.

 Let's say you want to handle "MyWebServiceException", you can create an ExceptionMapper "MyWebServiceExceptionMapper" like this:
@Provider
public class MyWebServiceExceptionMapper implements ExceptionMapper<MyWebServiceException> {

@Override
public Response toResponse(Exception e) {
GenericEntity<String> entity = new GenericEntity<String>(
   “{\"statusCode\":\"ERR-100\",\"responseData\":\"Error Processing Web Service\"}” ){};
return Response.status(Status.OK).entity(entity).type(MediaType.APPLICATION_JSON).build();
}
}

In order for this to be registered with Jersey, you'll need to put it in a package that's being scanned by Jersey to be resources or providers, so in the web.xml, have something like this:
<init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>com.myws.resource;com.myws.provider</param-value>
</init-param>

In this example, I separated the packages for resources and providers, providing 2 packages to be scanned.

To handle each exception differently, just create as many ExceptionMapper classes as you wish, and put them in the same package to be picked up and registered.

You can also use this to return a different HTTP status code for different errors, but as mentioned in the comments of an earlier POST, that's not going to work well with cross-domain Javascript REST requests.

2 comments:

  1. how can I catch this exception in the client java program.

    Code snippet for service:
    public Response getEmp(JAXBElement empRequest) throws EmpNotFoundException{
    EmpResponse empResponse = new EmpResponse();
    if(empRequest.getValue().getId()==1){
    empResponse.setId(empRequest.getValue().getId());
    empResponse.setName(empRequest.getValue().getName());
    }else{
    throw new EmpNotFoundException("Wrong ID");
    }
    return Response.ok(empResponse).build();
    }

    Client program:

    ClientResponse response = r.type(MediaType.APPLICATION_XML).post(ClientResponse.class,request );
    System.out.println(response.getStatus());
    if(response.getStatus() == 200){
    EmpResponse empResponse = response.getEntity(EmpResponse.class);
    System.out.println(empResponse.getId() + "::"+empResponse.getName());
    }else{
    EmpNotFoundException exc = response.getEntity(EmpNotFoundException.class);
    System.out.println(exc.getMessage());
    }

    When server throw exception, I get following error in program
    500
    Oct 17, 2012 7:27:42 PM com.sun.jersey.api.client.ClientResponse getEntity
    SEVERE: A message body reader for Java class com.jd.exception.EmpNotFoundException, and Java type class com.jd.exception.EmpNotFoundException, and MIME media type text/html; charset=utf-8 was not found
    Oct 17, 2012 7:27:42 PM com.sun.jersey.api.client.ClientResponse getEntity
    SEVERE: The registered message body readers compatible with the MIME media type are:
    */* ->
    com.sun.jersey.core.impl.provider.entity.FormProvider
    com.sun.jersey.core.impl.provider.entity.StringProvider
    com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
    com.sun.jersey.core.impl.provider.entity.FileProvider
    com.sun.jersey.core.impl.provider.entity.InputStreamProvider
    com.sun.jersey.core.impl.provider.entity.DataSourceProvider
    com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
    com.sun.jersey.core.impl.provider.entity.ReaderProvider
    com.sun.jersey.core.impl.provider.entity.DocumentProvider
    com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
    com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
    com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
    com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
    com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
    com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
    com.sun.jersey.core.impl.provider.entity.EntityHolderReader

    Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class com.jd.exception.EmpNotFoundException, and Java type class com.jd.exception.EmpNotFoundException, and MIME media type text/html; charset=utf-8 was not found
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:561)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
    at com.jd.client.EmpClient.main(EmpClient.java:30)


    Please help

    ReplyDelete
    Replies
    1. If I use Rest Client, I get HTML response. Snippet as I cant post HTML here.

      javax.servlet.ServletException: com.jd.exception.EmpNotFoundException: Wrong ID
      com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420)
      com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
      com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      com.jd.exception.EmpNotFoundException: Wrong ID
      com.jd.router.EmpRouter.getEmp(EmpRouter.java:27)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      java.lang.reflect.Method.invoke(Method.java:597)
      com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
      com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
      com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
      com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
      com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
      com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
      com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
      com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
      com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480)
      com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411)
      com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)
      com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)
      com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
      com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
      com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

      Delete