Previous Topic

Next Topic

Book Contents

Book Index

Registering JAX-RS Providers with JAX-RS Container

Provides information about registering JAX-RS providers with JAX-RS container.

The JAX-RS runtime may be extended using application-supplied provider classes. A provider is annotated with @Provider and implements one or more interfaces defined by JAX-RS. By default a single instance of each provider class is instantiated by the JAX-RS container for each JAX-RS application. First the constructor is called, then any requested dependencies are injected, then the appropriate provider methods may be called multiple times (simultaneously), and finally the object is made available for garbage collection. The specification defines several types of JAX-RS providers.

Entity Providers

Entity providers supply mapping services between representations and their associated Java types. There are two types of entity providers:

Message body readers and writers may restrict the media types they support using the @Consumes and @Produces annotations respectively.

The following example demonstrates a simple JAX-RS message body writer definition:

@Provider
@Produces("text/html")
public class BookWriter  implements MessageBodyWriter<BookResource> {

   private static final String BOOK_PATTERN="<table>"
      +  "<tr><td>ID:</td><td>{0}</td></tr>"
      +  "<tr><td>Author:</td><td>{1}</td></tr>"
      +  "<tr><td>Title:</td><td>{2}</td></tr>"
      +  "<tr><td>Count:</td><td>{3}</td></tr>"
      +  "</table>";

  /**
   * @see javax.ws.rs.ext.MessageBodyWriter#isWriteable(java.lang. Class, java.lang.reflect.Type,
   *      java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType)
   */
  @Override
   public boolean isWriteable( Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
     return BookResource.class.isAssignableFrom(type);
  }

  /**
   * @see javax.ws.rs.ext.MessageBodyWriter#getSize(java.lang. Object, java.lang. Class, java.lang.reflect.Type,
   *      java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType)
   */
  @Override
   public long getSize(BookResource t,  Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
     return -1;
  }

  /**
   * @see javax.ws.rs.ext.MessageBodyWriter#writeTo(java.lang. Object, java.lang. Class, java.lang.reflect.Type,
   *      java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap,
   *      java.io.OutputStream)
   */
  @Override
   public void writeTo(BookResource bookResource,  Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
      MultivaluedMap< String,  Object> httpHeaders, OutputStream entityStream)  throws IOException {
    entityStream.write(MessageFormat.format(BOOK_PATTERN, bookResource.getId(), bookResource.getAuthor(),
      bookResource.getTitle(), bookResource.getCount()).getBytes( "UTF-8"));
    entityStream.flush();
  }
}

Context Providers

Context providers supply context to resource classes and other providers. A context provider class implements the ContextResolver<T> interface and is annotated with @Provider. The following example demonstrates a simple JAX-RS context provider definition:

@Provider
public class RequestContextResolver  implements ContextResolver<RequestContext> {

  @Context
   private HttpServletRequest request;

  /**
   * @see javax.ws.rs.ext.ContextResolver#getContext(java.lang. Class)
   */
  @Override
   public RequestContext getContext( Class<?> type) {
     if (RequestContext.class.equals(type)) {
       return new RequestContext(request);
    }
     return null;
  }

}

Exception Mapping Providers

When a resource class or provider method throws an exception, the JAX-RS runtime will attempt to map the exception to a suitable HTTP response. An application can supply exception mapping providers to customize this mapping. Exception mapping providers map a checked or runtime exception to an instance of Response. An exception mapping provider implements the ExceptionMapper<T> interface and is annotated with @Provider. When a resource method throws an exception for which there is an exception mapping provider, the matching provider is used to obtain a Response instance. The resulting Response is processed as if the method throwing the exception had instead returned the Response. The following example demonstrates a simple JAX-RS exception mapper definition:

@Provider
public class DefaultExceptionMapper  implements ExceptionMapper<Throwable> {

  /**
   * @see javax.ws.rs.ext.ExceptionMapper#toResponse(java.lang.Throwable)
   */
  @Override
   public Response toResponse(Throwable e) {
     if (e  instanceof WebApplicationException) {
      WebApplicationException ex=(WebApplicationException) e;
       return ex.getResponse();
    }
     if (e  instanceof SecurityException) {
       return ErrorDescriptionUtils.getResponse(HttpURLConnection.HTTP_FORBIDDEN,
          GeneralErrorCodes.INSUFFICIENT_PERMISSIONS,  "Insufficient permissions",  null,  null,
          ErrorDescriptionUtils.UNKNOWN_EXCEPTION_CODE, e);
    }
     return ErrorDescriptionUtils.getResponse(HttpURLConnection.HTTP_INTERNAL_ERROR,
        GeneralErrorCodes.UNKNOWN_EXCEPTION,  "Unexpected error occurred",  null,  null,
        ErrorDescriptionUtils.UNKNOWN_EXCEPTION_CODE,
        e);
  }
}

Registering JAX-RS Providers

For more information about JAX-RS providers and code samples, please see JAX-RS:The Java API for RESTful Web Services > JAX-RS Provider

In the context of OSGi, JAX-RS providers which are registered as OSGi services are tracked by the OSGi JAX-RS publisher and registered with the Jersey JAX-RS container. It is recommended that JAX-RS provider instances are registered under the specific JAX-RS provider interfaces implemented, as well, in order to improve maintainability, ease debugging procedures and make the instance recognizable by the JAX-RS providers tracking utility.

The following code snippet demonstrates the registration of a JAX-RS message body writer as an OSGi service under javax.ws.rs.ext.MessageBodyWriter interfaces using declarative services annotations. The provider's priority is set to ENTITY_CODER which overwrites the default USER priority of the currently available Jackson JAX-RS provider. The complete code of the BookWriter JAX-RS message body writer can be found at JAX-RS:The Java API for RESTful Web Services > JAX-RS Providers.

@Provider

@Priority(Priorities.ENTITY_CODER)

@Produces("text/html")

@Component(service = MessageBodyWriter.class,

           configurationPolicy = ConfigurationPolicy.IGNORE)

public class BookWriter implements MessageBodyWriter<BookResource> {

    // implement message body writer methods

     ...

}