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

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


Листинг 15.14. Использование UriBuilder

>public class URIBuilderTest {

>··@Test

>··public void shouldBuildURIs() {

>····URI uri = 

>····UriBuilder.fromUri("http://www.myserver.com"). path("book"). path("1234"). build();

>····assertEquals("http://www.myserver.com/book/1234", uri.toString());


>····uri = UriBuilder.fromUri("http://www.myserver.com"). path("book") 

>··········.queryParam("author", "Goncalves"). build();

>····assertEquals("http://www.myserver.com/book?author=Goncalves", 

>·················uri.toString());


>····uri = UriBuilder.fromUri("http://www.myserver.com"). path("book") 

>·········.matrixParam("author", "Goncalves"). build();

>····assertEquals("http://www.myserver.com/book;author=Goncalves", uri.toString());

>····uri = UriBuilder.fromUri("http://www.myserver.com"). path("{path} ") 

>·········.queryParam("author", "{value}"). build("book", "Goncalves");

>····assertEquals("http://www.myserver.com/book?author=Goncalves", 

>·················uri.toString());


>····uri = UriBuilder.fromResource(BookRestService.class). path("1234"). build();

>····assertEquals("/book/1234", uri.toString());


>····uri = UriBuilder.fromUri("http://www.myserver.com"). fragment("book"). build ();

>····assertEquals("http://www.myserver.com/#book", uri.toString());

>··}

>}

Контекстная информация

Когда происходит обработка ресурса, поставщику ресурса для правильного выполнения запроса требуется контекстная информация. Аннотация @javax.ws.rs.core.Context предназначена для внедрения в атрибут или параметр метода следующих классов: HttpHeaders, UriInfo, Request, SecurityContext и Providers. Например, в листинге 15.15 показан код, внедряющий UriInfo таким образом, что этот класс может строить URI, а также добавляющий HttpHeaders для возвращения определенной заголовочной информации.


Листинг 15.15. Ресурс Customer, получающий HttpHeaders и UriInfo

>@Path("/customer")

>public class CustomerRestService {

>··@Context

>··UriInfo uriInfo;


>··@Inject

>··private CustomerEJB customerEJB;


>··@GET

>··@Path("media")

>··public String getDefaultMediaType(@Context HttpHeaders headers) {

>····List mediaTypes = headers.getAcceptableMediaTypes();

>····return mediaTypes.get(0). toString();

>··}


>··@GET

>··@Path("language")

>··public String getDefaultLanguage(@Context HttpHeaders headers) {

>····List mediaTypes = 

>······headers.getRequestHeader(HttpHeaders.ACCEPT_LANGUAGE);

>····return mediaTypes.get(0);

>··}


>··@POST

>··@Consumes(MediaType.APPLICATION_XML)

>··public Response createCustomer(Customer cust) {

>····Customer customer = customerEJB.persist(cust);


>····URI bookUri = 

>······uriInfo.getAbsolutePathBuilder(). path(customer.getId()). build();

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

>··}

>}

Как было показано выше в примерах с HTTP, информация передается между клиентом и сервером не только в теле объекта, но и в заголовках (Date, Server, Content-Type и т. д.). HTTP-заголовки участвуют в работе единообразного интерфейса, а веб-службы REST используют их «в оригинальных значениях». Вам как разработчику ресурсов может понадобиться доступ к HTTP-заголовкам. Именно для этого служит интерфейс javax.ws.rs.core.HttpHeaders. Экземпляр HttpHeaders можно внедрить в атрибут или параметр метода с помощью аннотации @Context, так как класс HttpHeaders — это словарь с вспомогательными методами для доступа к значениям заголовков без учета регистра. В листинге 15.15 служба возвращает стандартные значения Accept-Language и MediaType.


Примечание

В JAX-RS 2.0 аннотация @Context используется при внедрении контекстной информации. К сожалению, аннотация @Inject здесь не сработает, так как в данной версии выравнивание CDI не может быть полностью заархивировано. Остается надеяться, что в будущих версиях JAX-RS мы сможем широко использовать CDI и работать всего с одной аннотацией: @Inject.

Поставщик объектов

Когда мы получаем объекты в запросах или отсылаем в ответах, реализации JAX-RS требуется способ для преобразования представлений в тип Java и обратно. Эту работу выполняют поставщики объектов, обеспечивающие отображение между представлениями и ассоциированными с ними типами Java. В качестве примера можно привести JAXB, который отображает объект на XML-представление и наоборот. Если стандартных поставщиков XML и JSON недостаточно, то вы можете разработать собственные специальные поставщики объектов. Можете даже определить для этого свой формат. В таком случае потребуется предоставить среде времени исполнения JAX-RS способ для считывания/записи вашего специального формата в объект или из него, реализовав для этого собственный поставщик объектов. Существует две разновидности поставщиков объектов: MessageBodyReader и MessageBodyWriter.

Допустим, вы хотите перевести ваш компонент Customer в custom/format, чтобы он принял вид 1234/John/Smith. Как видите, в качестве разделителя используется символ /, причем первый маркер — это пользовательский идентификатор, второй — имя, последний — фамилия. В первую очередь вам потребуется класс (записывающий), который будет принимать компонент Customer и отображать его в теле ответа. В листинге 15.16 показан класс CustomCustomerWriter, который должен реализовывать интерфейс javax.ws.rs.ext.MessageBodyWriter и сопровождаться аннотацией @Provider. Аннотация @Produces указывает наш специальный медиатип ("custom/format"). Как видите, метод writeTo преобразует компонент Customer в поток данных, следующий за специальным форматом.


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