Вот краткое руководство по созданию веб-сервиса 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.
- Добавьте аннотацию @Stateless в класс SimpleService и поле менеджера сущностей с аннотацией @PersistenceContext вместе с методами получения и установки.
- Добавьте новый метод, чтобы вернуть имя курса для данного параметра идентификатора курса. Мы вернем это как текст в настоящее время:
@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.