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

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

APPLICATION_XHTML_XML"application/xhtml+xml"
APPLICATION_XML"application/xml"
MULTIPART_FORM_DATA"multipart/form-data"
TEXT_HTML"text/html"
TEXT_PLAIN"text/plain"
TEXT_XML"text/xml"
WILDCARD"*/*"

Если в методе используются аннотации @Consumes и @Produces, то они переопределяют любые аннотации, которыми может сопровождаться класс ресурса для аргумента метода или возвращаемого типа. При отсутствии любой из двух этих аннотаций предполагается поддержка любого медиатипа (*/*). По умолчанию CustomerRestService порождает обычные текстовые представления, которые переопределяются в некоторых методах (листинг 15.11). Обратите внимание: getAsJsonAndXML порождает массив представлений (XML или JSON).


Листинг 15.11. Ресурс Customer с несколькими представлениями

>@Path("/customer")

>@Produces(MediaType.TEXT_PLAIN)

>public class CustomerRestService {

>··@GET

>··public Response getAsPlainText() {

>····//…

>··}


>··@GET

>··@Produces(MediaType.TEXT_HTML)

>··public Response getAsHtml() {

>····//…

>··}


>··@GET

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

>··public Response getAsJsonAndXML() {

>····//…

>··}

>··@PUT

>··@Consumes(MediaType.TEXT_PLAIN)

>··public void putName(String customer) {

>····//…

>··}

>}

Если веб-служба REST в состоянии произвести более одного медиатипа, то целевой метод будет соответствовать наиболее приемлемому медиатипу согласно информации, указанной клиентом в заголовке Accept HTTP-запроса. Например, если заголовок Accept таков:

>Accept: text/plain

а URI при этом — /customer, то будет вызван метод getAsPlainText(). Но клиент мог бы использовать и такой HTTP-заголовок:

>Accept: text/plain; q=0.8, text/html

Он объявляет, что клиент может принимать медиатипы text/plain и text/html, но предпочитает второй. Для указания выбора используется коэффициент качества (он же — вес предпочтения), равный 0,8 («Я предпочитаю text/html, но пришлите мне text/plain, если это наилучший доступный вариант после 80 %-ного снижения качества»). При включении такого заголовка и указании на URI /customer будет вызван метод getAsHtml().

Возвращаемые типы

До сих пор мы в основном говорили о том, как вызывать метод (с помощью параметров, медиатипа, HTTP-операций…), а возвращаемый тип нас не интересовал. Что же может возвращать веб-служба в стиле REST? Как и любой класс Java, метод может возвратить любой стандартный тип Java, компонент JAXB и вообще любой объект, обладающий текстовым представлением, которое можно передать по протоколу HTTP. В данном случае среда времени исполнения определяет MIME-тип возвращаемого объекта и вызывает соответствующий поставщик объектов (Entity Provider, см. ниже) для получения нужного представления. Среда времени исполнения также определяет подходящий код состояния, который HTTP должен вернуть потребителю (например, 204 — Нет содержимого, если возвращаемый тип метода ресурса равен void или null; либо 200 — Хорошо, если возвращено ненулевое значение). Но иногда требуется более тщательный контроль над возвращаемой информацией: разумеется, вас интересует тело ответа, называемое в терминологии HTTP объектом, но также могут быть важны и код ответа, и/или заголовки и cookie ответа. В таких случаях вы возвращаете объект Reponse. Целесообразно возвращать javax.ws.rs.core.Response, поскольку так гарантируется тип возвращаемого содержимого. В листинге 15.12 показаны различные возвращаемые типы.


Листинг 15.12. Служба Customer, возвращающая типы данных, компонент JAXB и ответ

>@Path("/customer")

>public class CustomerRestService {

>··@GET

>··public String getAsPlainText() {

>····return new Customer("Джон", "Смит", "[email protected]", 

>························"12 34565"). toString();

>··}


>··@GET

>··@Path("maxbonus")

>··public Long getMaximumBonusAllowed() {

>····return 1234L;

>··}


>··@GET

>··@Produces(MediaType.APPLICATION_XML)

>··public Customer getAsXML() {

>····return new Customer("Джон", "Смит", "[email protected]", "12 34565");

>··}


>··@GET

>··@Produces(MediaType.APPLICATION_JSON)

>··public Response getAsJson() {

>····return Response.ok(new Customer("Джон", "Смит", "[email protected]", 

>··························"12 34565"), MediaType.APPLICATION_JSON). build();

>··}

>}

Метод getAsPlainText возвращает строковое представление потребителя, а метод getMaximumBonusAllowed — числовую константу. Будут применяться настройки, заданные по умолчанию, поэтому код состояния для обоих методов при возврате будет равен 200 — Хорошо, если не произойдет исключения. Метод getAsXML возвращает объект Customer JAXB POJO. Это означает, что среда времени исполнения выполнит маршалинг объекта в XML-представление.

Метод getAsJson возвращает не HTML-объект, а объект javax.ws.rs.core.Response. Response оборачивает HTML-объект, возвращаемый потребителю, и инстанцируется с помощью класса ResponseBuilder, используемого в качестве фабрики. В данном примере мы по-прежнему хотим вернуть JAXB-объект (Customer) с кодом состояния 200 — Хорошо (метод ok()), но также собираемся указать JSON в качестве MIME-типа. При вызове метода ResponseBuilder.build() создается конечный экземпляр Response.

Рекомендуется возвращать пользовательский Response для всех запросов, а не для самого HTML-объекта (при необходимости вы можете затем задать нужный код состояния). В табл. 15.6 показано подмножество Response API.


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