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

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

Один из методов, которым обладает веб-служба в стиле REST, получает все книги из базы данных. Этот метод мог бы вернуть List, но в таком случае не получился бы JAXB-маршалинг. Чтобы иметь XML-представление списка книг, нам понадобится POJO, аннотированный JAXB. Как показано в листинге 15.21, класс Books наследует от ArrayList и имеет аннотацию @XmlRootElement.


Листинг 15.21. JAXB-компонент Books, содержащий список Book

>@XmlRootElement

>@XmlSeeAlso(Book.class)

>public class Books extends ArrayList {

>··public Books() {

>····super();

>··}


>··public Books(Collection c) {

>····super(c);

>··}


>··@XmlElement(name = "book")

>··public List getBooks() {

>····return this;

>··}


>··public void setBooks(List books) {

>····this.addAll(books);

>··}

>}

Написание службы BookRestService

BookRestService — это веб-служба в стиле REST, реализованная как не сохраняющий состояние сеансовый компонент. Она использует менеджер объектов, позволяющий создавать, получать и удалять книги. Разделим эту службу на несколько частей и объясним каждую из них.


Заголовок

Заголовок BookRestService (листинг 15.22) очень важен, так как использует несколько аннотаций метаданных. В JAX-RS пользователи обращаются к службам, вызывая URI. Аннотация @Path("/book") указывает корневой путь ресурса (URL, по которому можно обратиться к этому ресурсу). В данном случае идентификатор ресурса будет примерно таким: http://localhost:8080/book.


Листинг 15.22. Заголовок BookRestService

>@Path("/book")

>@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

>@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

>@Stateless

>public class BookRestService {

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

>··private EntityManager em;

>··@Context

>··private UriInfo uriInfo;

>··//…

Аннотации @Produces и @Consumes определяют задаваемый по умолчанию тип содержимого, который будет производиться или использоваться этим ресурсом: XML или JSON. Наконец, мы находим здесь аннотацию @Stateless, подробно рассмотренную в главе 7. Она информирует контейнер о том, что веб-служба в стиле REST должна интерпретироваться как EJB и обеспечивать разграничение транзакций при обращениях к базе данных. В эту службу внедрена ссылка на менеджер объектов, а также UriInfo.


Создание новой книги

Придерживаясь семантики REST, мы используем HTTP-операцию POST для создания нового ресурса на XML или JSON (в зависимости от того, что указано в заголовке с аннотацией @Consumes). По умолчанию любой метод использует XML или JSON, это же верно для метода createBook(). Как показано в листинге 15.23, метод принимает Book в качестве параметра; не забывайте, что сущность Book также является объектом JAXB и после выполнения демаршалинга XML в объект Book менеджер объектов может долговременно сохранить его. Если параметр book является нулевым, генерируется исключение BadRequestException (код состояния 400 — Неверный запрос).


Листинг 15.23. Метод createBook службы BookRestService

>··//…

>··@POST

>··public Response createBook(Book book) {

>····if (book == null)

>······throw new BadRequestException();


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

>····URI bookUri = uriInfo.getAbsolutePathBuilder(). path(book.getId()). build();

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

>··}

>··//…

Этот метод возвращает Response, представляющий собой URI свежей записи о книге. Мы могли бы вернуть код состояния 200 — Хорошо (Response.ok()), указывающий, что создание записи о книге прошло успешно. Но в соответствии с принципами REST метод должен возвращать код 201 (или 204), указывая, что запрос был выполнен и привел к созданию нового ресурса (Response.created()). На новоиспеченный ресурс можно сослаться по URI, возвращенному в ответе (bookUri).

Чтобы создать ресурс с помощью кода, приведенного в листинге 15.23, нам потребуется отослать информацию в XML или JSON. Текст JSON менее пространен. Инструмент командной строки cURL использует метод POST и передает информацию в формате JSON. Эта информация должна соответствовать правилам отображения JSON/XML, действующим в Jersey (также не забывайте, что XML, в свою очередь, отображается с объекта Book по правилам JAXB):

>$ curl — X POST — data-binary "{\"description\":\"Научно-фантастическая книга\", 

>\"illustrations\":false,\"isbn\":\"1-84023-742-2\",\"nbOfPage\":354, 

>\"price\":12.5,\"title\":\"Автостопом по Галактике\"}" 

>-H "Content-Type: application/json" 

>http://localhost:8080/chapter15-service-1.0/rs/book — v

Развернутый режим вывода cURL (с аргументом — v) отображает HTTP-запрос и ответ (см. следующий вывод). В ответе вы видите URI созданной книги, причем идентификатор этого ресурса равен 601:

>> POST /chapter15-service-1.0/rs/book HTTP/1.1

>> User-Agent: curl/7.23.1 (x86_64-apple-darwin11.2.0) libcurl/7.23.1

>> Host: localhost:8080

>> Accept: */*

>> Content-Type: application/json

>> Content-Length: 165

>>

>< HTTP/1.1 201 Created

>< Server: GlassFish Server Open Source Edition 4.0

>< Location: http://localhost:8080/chapter15-service-1.0/rs/book/601

>< Date: Thu, 29 Nov 2012 21:49:44 GMT

>< Content-Length: 0


Получение книги по ID

Чтобы получить книгу по ее идентификатору, нужно использовать в запросе URL /book/{id книги}. id применяется в качестве параметра для нахождения книги в базе данных. Если в листинге 15.24 книга не найдена, то генерируется исключение NotFoundException (404). В зависимости от MIME-типа метод getBook() вернет представление записи книги в XML или JSON.


Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.