Статьи

Простые веб-сервисы RESTful с Glassfish

Вот краткое руководство по созданию веб-сервиса RESTful с Glassfish с использованием JAX-RS.

Сначала создайте новый проект maven под названием restwebdemo, используя jee6-sandbox-archetype, чтобы у нас была модель и некоторые данные для работы. Чтобы это работало со Glassfish, откройте файл persistence.xml и измените имя источника данных jta на jdbc / __ default. Также убедитесь, что javaDB запущен и работает, перейдя в $ glassfish_dir / bin и набрав asadmin start-database. Убедитесь, что приложение работает правильно, перейдя по адресу http: // localhost: 8080 / restwebdemo /, и вы должны получить список курсов.

Прежде чем мы перейдем к интересным вещам, у нас есть еще одна скучная часть конфигурации для выполнения конкретных веб-сервисов. Нам нужно добавить контейнер сервлетов джерси в наш файл web.xml:

<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Это также говорит Джерси обрабатывать URL, начинающиеся с / rest, и передавать их нашим методам веб-сервиса.

Теперь мы можем погрузиться прямо в создание нового серверного компонента, который будет отвечать на запросы веб-сервисов. Сейчас мы просто вернем простое сообщение из POJO.

@Path("sample")
public class SimpleService {

@Path("greet")
@GET
public String doGreet() {
return "Hello Stranger, the time is "+ new Date();
}
}

Аннотация пути к классу указывает, что это корневой ресурсный класс, а указанное значение пути указывает базовый URI для всех методов веб-службы, содержащихся в классе.
В методе doGreet у нас есть @Path, который используется для указания шаблона пути, которому этот метод должен соответствовать. Аннотация @GET используется для различения метода подресурса, который обрабатывает фактический запрос веб-службы, и метода локатора подресурса, который возвращает объект, который вместо этого будет использоваться для обработки запроса. В этом случае метод имеет аннотацию @GET, которая означает, что этот метод обрабатывает запрос и возвращает результат.
Если вы перейдете по адресу http: // localhost: 8080 / restwebdemo / rest / sample / greet /, вы должны увидеть приветственное сообщение с текущей датой и временем.

Теперь мы рассмотрим добавление параметризованных веб-сервисов, которые извлекают параметры из URL-адреса запроса и используют их для формирования выходных данных. Добавьте следующий метод в класс веб-службы:

@Path("sayHello/{name}")
@GET
public String doSayHello(@PathParam("name") String name) {
return "Hello there "+name;
}

Опять же, у нас есть аннотация пути, чтобы указать, каким URL будет соответствовать этот метод, и на этот раз мы добавили {имя} к URL. Это позволяет нам извлечь часть URL и дать ему имя. Это имя используется в аннотации @PathParam в сигнатуре метода для назначения фрагмента URL параметру name. Чтобы протестировать наш новый метод, повторно разверните приложение и перейдите по URL-адресу http: // localhost: 8080 / restwebdemo / rest / sample / sayHello / Andy, чтобы получить ответ Здравствуйте, Энди

Мы также можем использовать параметры запроса для предоставления значений методу с помощью аннотации @QueryParam. Мы создадим другой метод, который аналогичен, но вместо этого использует параметр запроса.

@Path("sayHello")
@GET
public String doSayHelloWithRequestParam(@QueryParam("name") String name) {
return "Hi there "+name;
}

На этот раз используемым URL-адресом будет http: // localhost: 8080 / restwebdemo / rest / sample / sayHello? Name = Andy, чтобы получить то же сообщение.

Чтобы сделать вещи более интересными, давайте добавим новую страницу, которая позволит нам ввести имя в форму и отправить его в веб-службу. Добавьте новую страницу с именем form.html со следующим содержанием:

<html>
<head>
<title>Insert title here</title>
</head>
<body>
<form action="rest/sample/sayHello" method="GET">
Name <input id="name" name="name"/> <input type="submit" />
</form>
</body>
</html>

Перейдите на эту страницу по адресу http: // localhost: 8080 / restwebdemo / form.html , введите свое имя и нажмите «Отправить». На следующей странице вас встретят по имени.

Обратите внимание, что нам пришлось установить метод формы в GET, потому что наш веб-сервис настроен только для ответа на запросы GET. Если мы изменим метод формы на POST, мы можем получить следующее сообщение об ошибке:

HTTP Status 405 - Method Not Allowed
type Status report
message Method Not Allowed
description The specified HTTP method is not allowed for the requested resource (Method Not Allowed).

Помните, что с REST эти фактические глаголы имеют значение и добавляют значение к запросу, поэтому он строго соответствует тому, как он соответствует вызываемому методу.

Чтобы решить эту проблему, мы можем добавить новый метод для обработки форм POST, например:

@Path("sayHello")
@POST
public String doSayHelloWithFormParam(@FormParam("name") String name) {
return "Hi there " + name;
}

Здесь мы изменили @GET на @POST, чтобы разрешить другой глагол, и изменили аннотацию для параметра метода имени на @FormParam. Путь остается тем же, потому что у нас могут быть методы обслуживания, которые соответствуют одному и тому же пути, но для разных глаголов запроса. Мы можем даже иметь один и тот же глагол и путь, если возвращаемый тип содержимого отличается. Тип содержимого используется для указания типа вывода, возвращаемого методом. Это устанавливается путем добавления @ javax.ws.rs.Produces (не путать с аннотацией CDI Productions). Аннотация принимает строковый параметр, который указывает тип носителя, возвращаемого методом. Общие типы мультимедиа определены как константы в классе MediaType, поэтому вы можете использовать:

@Path("sayHello")
@POST
@Produces(MediaType.APPLICATION_XML)
public String doSayHelloWithFormParam(@FormParam("name") String name) {
return "<message>Hi there " + name+"</message>";
}

Если вы снова запустите свою форму и опубликуете ее, вы получите xml-ответ следующим образом:

<message>Hi there Andy</message>

В зависимости от вашего браузера, если вы вернете только текст, вы получите ошибку, потому что обычный текст не является допустимым XML, а браузер ожидает XML, потому что это тип ответа, установленный в ответе от веб-службы.

Чтобы закончить, мы собираемся сделать что-то более интересное, мы создадим веб-сервис, который будет возвращать название курса из базы данных, используя данные песочницы, встроенные в архетип. По разным причинам мы выберем самый прямой путь к получению доступа к данным, который состоит в том, чтобы сделать компонент веб-службы компонентом без сохранения состояния и внедрить контекст постоянства, используя аннотацию @PersistenceContext.

  1. Добавьте аннотацию @Stateless в класс SimpleService и поле менеджера сущностей с аннотацией @PersistenceContext вместе с методами получения и установки.
  2. Добавьте новый метод, чтобы вернуть имя курса для данного параметра идентификатора курса. Мы вернем это как текст в настоящее время:

 

@Path("courseName/{id}")
@GET
public String getCourseNameFromId(@PathParam("id") Long id) {
Course c = entityManager.find(Course.class, id);
if (c == null) {
return "Not Found, try the index <a href='/restwebdemo/'>page</a> and come back";
} else {
return c.getTitle();
}
}

Обратите внимание, что происходит автоматическое преобразование типов, и значение автоматически преобразуется в Long. Если курс не найден, мы предлагаем пользователю перейти на главную страницу демоверсии. Мы не просто слишком полезны, тестовые данные генерируются, когда вы запрашиваете одну из страниц приложения в первый раз. В текущем контексте персистентности при повторном развертывании база данных удаляется и перестраивается, поэтому она будет пустой. Вам нужно перейти на первую страницу, чтобы автоматически создать данные, а затем вернуться на свою страницу, чтобы просмотреть курс. Пример URL-адреса: http: // localhost: 8080 / restwebdemo / rest / sample / courseName / 124 .

Конечно, вы можете получить объект курса и создать свой собственный ответ XML или JSON, чтобы отправить его обратно клиенту, или использовать стороннюю библиотеку, такую ​​как Jackson, для создания ответа JSON. Однако, как мы увидим в следующий раз, в Java EE 6 есть все эти полезности, встроенные для нас, и с помощью нескольких аннотаций мы будем перемещать объекты туда-сюда в самое короткое время.

Вы можете скачать исходный код проекта здесь . Просто разархивируйте, соберите с maven (пакет mvn clean) и разверните на Glassfish.