T.M. SoftStudio

feci quod potui, faciant meliora potentes

JAX-RS API

Пакет javax.ws.rs.ext

Пакет javax.ws.rs.ext обеспечивает связывание между представлениями ресурса и Java-типами и позволяет создать собственные классы, расширяющие среду выполнения JAX-RS.

Классы поставщиков, обеспечивающие связывание с Java-типами, маркируются аннотацией @Provider и реализуют один из интерфейсов MessageBodyReader, MessageBodyWriter, ContextResolver и ExceptionMapper в зависимости от их предназначения.

Классы поставщиков, реализующие интерфейс MessageBodyReader или MessageBodyWriter, называются Entity Providers, т. к. обеспечивают чтение и запись тела сообщения.

Интерфейс MessageBodyReader<T> демаршализует тело запроса в Java-тип и имеет следующие методы:

  • boolean isReadable(java.lang.Class<?> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType)

Вызывается средой выполнения JAX-RS для проверки, способен ли данный MessageBodyReader-класс осуществить демаршализацию тела запроса. Проверка соответствия передаваемого в качестве аргумента Java-типа может быть осуществлена с помощью различных методов сравнения, в том числе метода type.isAnnotationPresent(), проверяющего наличие определенных аннотаций в классе Java-типа.

  • T readFrom(java.lang.Class<T> type, java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType,
    MultivaluedMap<java.lang.String,java.lang.String> httpHeaders,
    java.io.InputStream entityStream)

Создает Java-объект из входящего потока тела запроса.

Интерфейс MessageBodyWriter<T> маршализует Java-тип в исходящий поток ответа и имеет следующие методы:

  • boolean isWriteable(java.lang.Class<?> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType)

Вызывается средой выполнения JAX-RS для проверки того, способен ли данный MessageBodyWriter-класс осуществить маршализацию Java-объекта.

  • long getSize(T t, java.lang.Class<?> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType)

Вызывается перед маршализацией для установки длины сериализованного объекта. Если длина не определяется, метод возвращает –1.

  • void writeTo(T t, java.lang.Class<?> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType,
    MultivaluedMap<java.lang.String,java.lang.Object> httpHeaders,
    java.io.OutputStream entityStream)

Записывает HTTP-ответ.

Для ограничения MIME-типов в классах Entity Providers применяются аннотации @Consumes и @Produces.

JAX-RS-реализация обеспечивает по умолчанию классы Entity Providers для маршализации/демаршализации в следующие Java-типы:

  • byte[] — MIME-тип */*;

  • java.lang.String — MIME-тип */*;

  • java.io.InputStream — MIME-тип */*;

  • java.io.Reader — MIME-тип */*;

  • java.io.File — MIME-тип */*;

  • javax.activation.DataSource — MIME-тип */*;

  • javax.xml.transform.Source — XML-тип text/xml, application/xml и application/*+xml;

  • javax.xml.bind.JAXBElement и JAXB-классы приложения — XML-тип text/xml, application/xml и application/*+xml;

  • MultivaluedMap<String,String> — application/x-www-form-urlencoded;

  • StreamingOutput — MIME-тип */*.

Таким образом, объекты вышеперечисленных типов могут без дополнительного кодирования возвращаться и потребляться методами @GET, @PUT и @POST ресурса. Если же методу ресурса необходимо возвращать объект другого Java-типа, тогда метод ресурса возвращает объект javax.ws.rs.core.Response, который создается с помощью класса javax.ws.rs.core.Response.ResponseBuilder и класса javax.ws.rs.core.GenericEntity<T>. Или же используется MessageBodyWriter-класс, позволяющий возвращать пользовательский Java-тип напрямую или как часть объекта javax.ws.rs.core.Response. Также, если методу ресурса @PUT необходимо использовать в качестве параметра нестандартный Java-объект, необходимо создать MessageBodyReader-класс, обеспечивающий демаршализацию запроса в Java-объект.

Из перечня стандартных для маршализации/демаршализации Java-типов видно, что методы ресурса могут возвращать и потреблять XML-данные, представленные JAXB-классами приложения. JAXB-классы приложения создаются с помощью JAXB-аннотаций @XmlRootElement, @XmlElement и т. д., а среда выполнения JAX-RS использует стандартную JAXBContext-реализацию для маршализации/демаршализации их экземпляров, отвечая за создание и инициализацию объекта JAXBContext. Если же приложению требуется самому конфигурировать объект JAXBContext, необходимо создать класс поставщика, маркированный аннотацией @Provider и реализующий интерфейс ContextResolver<T>, который имеет единственный метод T getContext(java.lang.Class<?> type), вызываемый средой выполнения JAX-RS для получения объекта JAXBContext. Ограничить MIME-типы ContextResolver-класса можно с помощью аннотации @Produces.

Выполнение методов ресурса или поставщика может вызывать исключительную ситуацию. При этом среда выполнения JAX-RS связывает ошибку с подходящим HTTP-ответом. Приложение может само определять такого рода связывания с помощью класса поставщика, маркированного аннотацией @Provider и реализующего интерфейс ExceptionMapper<E extends java.lang.Throwable>, который имеет единственный метод Response toResponse(E exception), связывающий Java-исключение с объектом Response.

Аннотация @Context может вводить, помимо объектов Application, UriInfo, Request, HttpHeaders и SecurityContext, объект Providers, реализующий интерфейс Providers, который имеет следующие методы.

  • <T> MessageBodyReader<T> getMessageBodyReader(java.lang.Class<T> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType)

Возвращает объект MessageBodyReader, соответствующий указанным критериям.

  • <T> MessageBodyWriter<T> getMessageBodyWriter(java.lang.Class<T> type,
    java.lang.reflect.Type genericType,
    java.lang.annotation.Annotation[] annotations, MediaType mediaType)

Возвращает объект MessageBodyWriter, соответствующий указанным критериям.

  • <T extends java.lang.Throwable> ExceptionMapper<T>
    getExceptionMapper(java.lang.Class<T> type)

Возвращает объект ExceptionMapper для указанного типа исключений.

  • <T> ContextResolver<T> getContextResolver(java.lang.Class<T>
    contextType, MediaType mediaType)

Возвращает объект ContextResolver, соответствующий указанным критериям.

Таким образом, с помощью введенного объекта Providers, можно получать объекты поставщиков, например, для создания классов поставщиков сложного типа или, скажем, для использования объекта JAXBContext, полученного с помощью ContextResolver, в MessageBodyReader- или MessageBodyWriter-классе.

Пакет javax.ws.rs.ext также содержит классы RuntimeDelegate и RuntimeDelegate.HeaderDelegate<T>, являющиеся внутренними для JAX-RS и используемые средой выполнения JAX-RS для создания таких объектов как Response.ResponseBuilder, UriBuilder, Variant.VariantListBuilder и для маршализации/демаршализации HTTP-заголовков.

Метод public abstract <T> T createEndpoint(Application application, java.lang.Class<T> endpointType) класса RuntimeDelegate может быть использован для развертывания JAX-RS-приложения на платформе Java SE.