JAX-RS Providers Part III

In this lesson, we are going to explore

  • Exception Mappers: how to transform low application level exceptions to logical HTTP reponses

  • Context Providers: provides context (of other classes) to resources and providers

Exception Mapper

The javax.ws.rs.core.Response object allows developers to wrap HTTP error state and return it to caller. A javax.ws.rs.WebApplicationException (unchecked exception) can be used as a bridge between the native business/domain specific exceptions and an equivalent HTTP error response. A javax.ws.rs.ext.ExceptionMapper represents a contract (interface) for a provider that maps Java exceptions to Response objects.

It's benefits are obvious

  • helps embrace “don’t repeat yourself” (DRY) principle. your exception detection and transformation logic is not repeated across all of your service methods

  • allows flexible mappings between business logic exceptions and the desired HTTP response

  • in addition to returning HTTP status codes, you can choose to return HTTP payload in the message body as well

Let's look at an example

//Custom exception mapper

public class BookNotFoundMapper implements
  ExceptionMapper<BookNotFoundException>{
     @Override
      Response toResponse(
        BookNotFoundException bnfe){
           return Response.status(404).build();
      }
}

In the above example, thanks to the exception mapper, a BookNotFoundException is converted to a HTTP 404 response to the caller

New exception hierarchy

JAX-RS 2.0 has been supplemented with unchecked exceptions that inherit from javax.ws.rs.WebApplicationException. This design relieves the developer from having to build and throw a WebApplicationException with explicit HTTP error information.

The new set of exceptions are intuitively named and each of them maps to a specific HTTP error scenario (by default) – this means that, throwing any of these exceptions from your resource classes would result in a pre-defined (as per mapping) HTTP error response being sent to the client e.g. the client would receive a HTTP 403 in case you throw a NotAuthorizedException. The exceptions’ behavior can also be modified at runtime by using the ExceptionMapper to return a different Response object.

Context Provider

Context services are provided by the implementation of ContextResolver interface (which has just one method).

  • Think of context as configuration metadata which can help with various aspects (instance creation etc.) and

  • the Context Provider as a factory for these contexts

//Simple Context Provider/Resolver

@Provider
@Produces("application/json")
public class MyCustomContextProvider implements ContextResolver<MyCustomContext> {

    public MyCustomContext getContext(){
        return new MyCustomContext();
    }
}
//Leveraging the Context Provider

public class Resource{

    @Context ctx
    Providers providers;

    @GET
    @Produces("application/json")
    public Response get(){

        //fetch it
        MyCustomContext customCtx = providers.
        getContextResolver(MyCustomContext.class
            ,MediaType.APPLICATION_JSON);

        //use it    
       MyCustomClass clazz = customCtx.create();
    }

}

Last updated