Я недавно начал работать с JAX-RS, и хочу заметить, очень удобный инструмент для создания RESTful веб-сервисов на Java. Ранее мы использовали для этого самописный фреймворк на сервлетах, но JAX-RS оказался куда продуктивне, гибче и проще в использовании. К чему я все это пишу? Просто решил рассказать об этой технологии, возможно кому-нибудь еще пригодится. Собственно JAX-RS это, фактически, набор аннотаций, которые позволяют описывать классы, методы в терминах RESTful.

Я заметил, что информация по REST на русской википедии довольно скудная, так что для начала расскажу в двух словах о том, что вообще такое REST.


REST




REST (Representational State Transfer) – это архитектурный подход в дизайне распределенных приложений, например, веб-сервисов.
Основными целями применения этого подхода являются: расширяемость (в плане введения новых компонент), унифицированных интерфейс доступа, независимое развертывание компонент.
REST-архитектура имеет несколько ограничений. Во-первых, данная архитектура описывает взаимодействие клиента и сервера, соответственно может применяться только для случаев, в которых есть клиент и сервер. Во-вторых, она не подразумевает зависимости от пользовательского контекста. В-третьих, унифицированный интерфейс, не позволяет посылать произвольные запросы.
REST-архитектура построенная на базе протокола HTTP, использует методы отправки запросов этого протокола GET, POST, PUT, DELETE, для определения действия, которое необходимо выполнить с входящими параметрами.
Основным понятием, на котором строится REST, является понятия ресурса (некоторого источника данных), который задается уникальным идентификатором (например, в HTTP это URI). При манипуляции с ресурсами используется некоторый стандартизированный интерфейс доступа. Ресурсы могут содержать в себе подресурсы (так же называемые дочерними ресурсами), которые содержат информацию о некоторой части ресурса.
Одним из наиболее распространенных применений REST являются RESTful веб-сервисы.

RESTful веб-сервис




RESTful веб-сервис (так же известный, как веб API) это веб-сервис построенный на основе HTTP и принципов REST. Это набор ресурсов, характеризующийся следующими признаками:
1. Базовый URI веб-сервиса, например http://yoursite.yourdomain/resources/.
2. Поддерживаемые типы данных.
3. Набор операций поддерживаемых сервисом, соответствующих HTTP-методам (GET, POST, PUT, DELETE и прочие).
4. API должен базироваться на гипертексте (то есть HTML) .
Теперь рассмотрим, как работают различные HTTP-методы для ресурсов и подресурсов:

Родительский ресурс http://yoursite.yourdomain/resources/resource1/




GET: Возвращает список дочерних ресурсов и (возможно) некоторые другие их особенности
POST: Создает новый дочерний элемент в коллекции resource1.
PUT: Полностью замещает ресурс resource1 (при этом новый resource1 может, например, перестать иметь дочерние ресурсы).
DELETE: Удаляет ресурс resource1 (естественно со всеми подресурсами).

Дочерний ресурс http://yoursite.yourdomain/resources/resource1/element1




GET: Возвращает детальное описание дочернего ресурса со всеми его особенностями
POST: Зачастую не используется для листовых узлов (то есть для ресурсов не имеющих подресурсов). Работает с подресурсом element1, как с коллекцией, добавляет к нему дочерний ресурс.
PUT: Замещает указанный дочерний ресурс, а в случае если его не существует, то создает.
DELETE: Удаляет ресурс element1.

Кроме того, метод GET не имеет побочных эффектов, то есть его вызов не изменяет данные соответствующего ресурса. А методы PUT и DELETE являются идемпотентными, то есть такими, что их повторное применение дает такой же результат, как и единоразовое.

JAX-RS




Для RESTful веб-сервиса, основными данными являются URI ресурса на сервере, и какой метод HTTP будет использоваться. JAX-RS определяет аннотации, с помощью которых можно получать эту информацию. Каждый класс, являющийся ресурсом, должен иметь, по крайней мере, одну из этих аннотаций.

Указание URI с помощью аннотации




Аннотация @Path указывает URI ресурса. Данная аннотация объявлена в javax.ws.rs.Path и может использоваться для того, чтобы помечать классы и методы. Она принимает один параметр: строку, являющуюся шаблоном URI ресурса.
Шаблон URI указывает местоположения ресурса. Как показано в примере, такой шаблон может содержать следующие компоненты: необрабатываемые компоненты пути и идентификаторы параметров, заключенные в фигурные скобки.
@Path("/resources/{resource}/{element}")



Приведенному шаблону будет, например, соответствовать URI /resources/database/users. Который может означать, например, запрос к таблице users из базы данных. Таким образом, значение resource будет равно database, а значение element равно users.
В зависимости от того, что помечаются аннотацией, шаблон будет применяться к полному пути (для корневого ресурса), либо к пути относительно родительского ресурса (для дочернего ресурса). Данное правило иллюстрирует следующий пример:
package demo.jaxrs;

import javax.ws.rs.Path;

@Path("/colorservice/")
public class ColorService
{
public ColorService()
{
...
}

@GET
@Path("/{colorCode }/")
public Color getColor(@PathParam("colorCode") String code)
{
...
}
}



В нем шаблон /colorservice/ - шаблон абсолютного URI, а шаблон /{colorCode }/ указан относительно /colorservice/.

Указание HTTP-метода с помощью аннотаций




В JAX-RS есть пять аннотаций относящиеся к соответствующим им HTTP методам: javax.ws.rs.DELETE, javax.ws.rs.GET, javax.ws.rs.POST, javax.ws.rs.PUT, javax.ws.rs.HEAD.
Для того, чтобы указать, что данный метод класса должен обрабатывать запросы отправленные некоторым HTTP методом, необходимо пометить данный метод класса соответствующей аннотацией, например, @GET или @DELETE.
Корневой ресурсный класс, является точкой входа в RESTful веб-сервис на JAX-RS. Он обозначен аннотацией @Path, указывающей URI корневого ресурса сервиса. Его методы либо напрямую реализуют операции с ресурсом, либо предоставляют доступ к подресурсам.

Требования к корневому ресурсному классу
• Данный класс должен быть обозначен аннотацией @Path.
Указанный путь является корневым URI для всех ресурсов обрабатываемых данным сервисом. Если класс корневого ресурса указывает, что его путь resource и один из его методов обозначен аннотацией GET, то GET-запрос на resource вызовет этот метод. Если подресурс указывает свой URI {id}, то полный шаблон пути к подресурсу будет resource/{id} и он будет обрабатывать запросы типа resource/42.
• Класс должен кметь публичный конструктор для вызова его в рантайме.
В рантайме должно быть возможно предоставить все входящие параметры конструктора. В качестве параметров конструктора могут использоваться параметры, отмеченные JAX-RS аннотациями, такими как @HeaderParam, @PathParam, @FormParam.

Как минимум один из методов класса должен быть помечен либо аннотацией HTTP-метода, либо аннотацией @Path.

package demo.jaxrs.server;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/customerservice/")
public class CustomerService
{
public CustomerService()
{
...
}

@GET
public Customer getCustomer(@QueryParam("id") String id)
{
...
}

@DELETE
public Response deleteCustomer(@QueryParam("id") String id)
{
...
}

@PUT
public Response updateCustomer(Customer customer)
{
...
}

@POST
public Response addCustomer(Customer customer)
{
...
}

@Path("/orders/{orderId}/")
public Order getOrder(@PathParam("orderId") String orderId)
{
...
}

}



Класс из описанного выше примера соответствует все приведенным требованиям.
Все выше приведенные аннотации, кроме @QueryParam уже были ранее описаны, эта аннотация указывает, что значение входящего параметра метода должно быть взято из параметров HTTP-запроса. Причем, строковый параметр аннотации задает ключ, по которому будет доступно необходимое значение в запросе.

Некоторые ограничения
Все методы ресурса должны соответствовать следующим условиям:
• Они должны быть публичными.
• Они должны быть отмечены одной из аннотаций HTTP-методов.
• Каждый из них не должен содержать более одного «параметра-сущности».

Параметры
Методы ресурса могут принимать два вида параметров:
«Параметры-сущности» — эти параметры не аннотированы, их значение формируется из данных пришедших в запросе. Параметры-сущности могут быть произвольного типа, для которого в приложении существует провайдер данных. Зачастую это объекты JAXB. Как уже упоминалось, в ресурсном методе может быть только один параметр-сущность
Аннотированные параметры — это параметры обозначенные аннотациями JAX-RS, которые указывают, каким образом значение параметра получается из запроса. Зачастую, значения параметров получаются из фрагментов запрошенного URI.
Данный пример иллюстрирует ресурсный метод имеющий входящие параметры обоих типов.

@POST
@Path("buildings/house/{id}")
public void buildAHouse(House house, @PathParam("id") String id)
{
...
}




Возвращаемые значения
Ресурсные методы могут возвращать одно из перечисленных ниже значений:
• void
• произвольный класс в Java, для которого в приложении есть провайдер данных
• объект типа javax.ws.rs.core.Response.
• объект типа javax.ws.rs.core.GenericEntity.
Все ресурсне методы возвращают отправителю запроса код ответа. Если возвращаемый методом тип void или возвращаемое значение null, то HTTP-код ответа 200. В случаи если метод возвращает другое значение, код ответа будет 204.
В целом, этой информации достаточно для реализации RESTful веб-сервиса, на JAX-RS. Несколько позже, я планирую написать еще о некоторых полезных особенностях этого фреймворка. Удачи в разработке.
0

Комментарии

Для того, чтоб оставлять комментарии или зарегистрируйтесь.