Изучаем Java EE 7 - [241]

Шрифт
Интервал

• служба должна быть объектом, не имеющим состояния, и не должна сохранять клиентоспецифичное состояние между вызовами методов.

Выполнение операций CRUD над веб-службами в стиле REST

В листинге 15.3 было показано, как написать очень простую REST-службу, возвращающую строку. Но в большинстве случаев вам нужно будет обращаться к базе данных, получая или сохраняя информацию по транзакционному принципу. Для таких целей также можно написать REST-службу и добавлять возможности сеансовых компонентов, не сохраняющих состояния. Чтобы обеспечить такой функционал, потребуется аннотация @Stateless. Так мы получим доступ к уровню сохраняемости (сущностям JPA), как показано в листинге 15.4.


Листинг 15.4. REST-служба Book, создающая, удаляющая и получающая информацию о книгах из базы данных

>@Path("book")

>@Stateless

>public class BookRestService {


>··@Context

>··private UriInfo uriInfo;

>··@PersistenceContext(unitName = "chapter15PU")

>··private EntityManager em;


>··@GET

>··@Produces(MediaType.APPLICATION_XML)

>··public Books getBooks() {

>····TypedQuery query = em.createNamedQuery(Book.FIND_ALL, Book.class);

>····Books books = new Books(query.getResultList());

>····return books;

>··}


>··@POST

>··@Consumes(MediaType.APPLICATION_XML)

>····public Response createBook(Book book) {

>····em.persist(book);

>····URI bookUri = 

>····uriInfo.getAbsolutePathBuilder(). path(book.getId(). toString()). build();

>····return Response.created(bookUri). build();

>··}


>··@DELETE

>··@Path("{id}")

>··public Response deleteBook(@PathParam("id") Long bookId) {

>····em.remove(em.find(Book.class, bookId));

>····return Response.noContent(). build();

>··}

>}

В коде из листинга 15.4 представлена REST-служба, которая может использовать и производить XML-представление книги. Метод getBooks() получает из базы данных список книг и возвращает XML-представление этого списка (используя согласование содержимого). Данное представление доступно через метод GET. Метод createBook() принимает XML-представление книги и сохраняет его в базе данных. Он вызывается с помощью HTTP-операции POST и возвращает ответ (Response) с URI (bookUri) новой книги, а также статус created. Метод deleteBook принимает идентификатор книги в качестве параметра и удаляет его из базы данных.

Код из листинга 15.4 построен по очень простой модели JAX-RS и использует набор очень мощных аннотаций. Теперь подробнее рассмотрим концепции, представленные в этом коде.

Определение URI и URI связывания

Аннотация @Path представляет относительный URI и может сопровождать класс или метод. При использовании с классами она ссылается на корневой ресурс, указывая корень дерева ресурсов и предоставляя доступ к подресурсам. В листинге 15.5 показана REST-служба, расположеная по ссылке http://www.myserver.com/items. Все методы этой службы будут иметь /items в качестве корня.


Листинг 15.5. Корневой путь к ресурсу Item

>@Path("/items")

>public class ItemRestService {

>··@GET

>··public Items getItems() {

>····//…

>··}

>}

Потом вы можете добавлять к вашим методам подпути. Это может быть полезно для объединения в группы общих функциональностей нескольких ресурсов, как показано в листинге 15.6 (пока можно абстрагироваться от того, какую роль играют аннотации @GET, @POST и @DELETE, так как они будут описаны подробнее в разделе «Сопоставление HTTP-методов»).


Листинг 15.6. Несколько подпутей у ItemRestService

>@Path("/items")

>public class ItemRestService {

>··@GET

>··public Items getItems() {

>····// URI: /items

>··}


>··@GET

>··@Path("/cds")

>··public CDs getCDs() {

>····// URI: /items/cds

>··}


>··@GET

>··@Path("/books")

>··public Books getBooks() {

>····// URI: /items/books

>··}


>··@POST

>··@Path("/book")

>··public Response createBook(Book book) {

>····// URI: /items/book

>··}

>}

В листинге 15.6 показана веб-служба с передачей состояния представления, которая будет предоставлять вам методы для получения всех элементов (компакт-дисков и книг) из приложения CD-Bookstore. При запросе корневого ресурса /items выбирается всего один метод без подчиненной аннотации @Path (getItems()). Затем, когда @Path будет сопровождать и класс и метод, относительный путь к методу будет получен конкатенацией обоих элементов. Например, путь для получения всех CD будет таким: /items/cds. При запросе /items/books будет вызван метод getBooks(). Чтобы создать новую запись о книге, необходимо указать на /items/book.

Если бы информация @Path("/items") сопровождала лишь класс, но не касалась ни одного метода, то для доступа к любому из методов использовался бы один и тот же путь. Единственным отличительным признаком стала бы HTTP-операция (GET, PUT и т. д.). Об этом мы поговорим ниже.

Извлечение параметров

При работе с REST для доступа к ресурсу очень важно иметь аккуратные URI, полученные при конкатенации путей. Но одних лишь путей и подпутей недостаточно. При оперировании веб-службами в стиле REST им необходимо передавать параметры, а также извлекать параметры и обрабатывать их во время исполнения. В листинге 15.4 было показано, как получить параметр из пути с аннотацией @javax.ws.rs.PathParam. В JAX-RS предоставляется широкий набор аннотаций для извлечения различных параметров, которые могут присутствовать в запросе (@PathParam, @QueryParam, @MatrixParam, @CookieParam, @HeaderParam и @FormParam).


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.