| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > RESTful веб-сервисы: Создание простого сервиса |
| Автор: powerOn 4.1.2009, 22:42 | ||||||||||||||||||||||
| Создание простого RESTful веб-сервиса с помощью JAX-RS и Mаven. Не так давно мне предстояло столкнуться RESTful веб-сервисами. Накопив определенный уровень знаний, я решил ими поделиться с вами. В данной статье я проведу небольшой обзор этой технологии, а так же покажу пример создания простого RESTful веб-сервиса на основе стека Jersey. Предполагается, что читатель имеет представления и простейшие навыки работы со следующими технологиями: Maven2, Любой контейнер сервлетов, HTTP протокол. REST – это стиль, стиль построения сервисов в Web окружении. Точно также можно сказать и про давно известные нам SOAP сервисы. Охарактеризовать последние можно тем, что они используют протокол, построенный на основе XML, который может быть использован поверх http или tcp (или какого либо другого) протокола. Сообщения трансформируются в xml, упаковываются в SOAP пакеты, передаются по сети от клиента к серверу и наоборот. С Restful сервисам дело обстоит немного по-другому: SOAP больше не нужен – взаимодействие построено непосредственно через http протокол и поэтому, его знание будет очень полезным при их создании. Сразу скажу, что, на мой взгляд, не стоит рассматривать SOAP и RESTful веб-сервисы конкурентами. Просто они пропагандируют разный стиль. Ряд задач естественно решать с помощью SOAP сервисов, например RPC, но существует и ряд тех, с которыми отлично справятся RESTful. Например, получение ресурсов веб-приложения (картинки, файлы и т.д.). Конечно, ограничивать только этим RESTful веб-сервисы не получится. Для описания того как должны работать RESTful веб-сервисы на платформе J2EE была разработана спецификация JAX-RS 1.0 (JSR-311). Заявляется, что они будут включены в Java EE 6, а в качестве реализации для сервера Glassfish V3 выступит стек Jersey. Но нам совсем не обязательно дожидаться релиза Glassfish V3, Jersey мы можем попробовать уже сейчас, на любом контейнере сервлетов, поддерживающим спецификацию 2.4 или выше (например, Tomcat 6 или Glassfish V2). И так, что нам понадобится для построения простейшего RESTful веб-севриса: 1) Любом контейнер сервлетов, поддерживающим спецификацию 2.4 или выше. В результате сборки, приложение будет представлять собой war-архив. 2) Maven 2 – понадобится для сборки. 3) Любимая IDE, желательно с поддержкой Maven – что бы код было удобнее писать и проект собирать. Шаг № 1 - Предварительный. Установите контейнер сервлетов (например, Tomcat 6), Maven и вашу любимую IDE. Шаг № 2 – Создание проекта. Существует 2 способа создать стартовый проект для начала работы с RESTful сервисами: 1) На основе jersey-quickstart-webapp архитипа:
2) На основе maven-archetype-webapp архитипа:
Первый способ удобен, проект создастся уже со всеми необходимыми зависимостями, настроенным web.xml и примером простого сервиса. Одно “но”: много зависимостей избыточны, разобраться с первого раза что нужно, а что нет, не так уж и просто. Поэтому, я покажу как создать проект с нуля, используя maven-archetype-webapp. Итак, создайте проект на основе maven-archetype-webapp, как показано в примере 2. В случае успешного выполнения, в текущем каталоге должна появиться папка myrestfulapp со следующей структурой директорий:
В каталоге main создайте каталог java. Тут будут находиться Java классы сервисов. Далее создайте класс сервиса – (обычный Java класс) в нашем случае будет com.mycompany.SimpleService:
В pom.xml необходимо добавить необходимые, а так же установить source level равным 1.5:
Далее поправим web.xml следующим образом:
Здесь важно обратить внимание на следующее: в web.xml был добавлен специальный сервлет com.sun.jersey.spi.container.servlet.ServletContainer, он отвечает за жизненный цикл RESTful сервисов. Параметр com.sun.jersey.config.property.packages указывает на пакет, который будет просканирован в поисках имплементации сервисов. Как только будет найден класс с аннотацией @Path, то Jersey попытается создать на его основе сервис. Параметр url-pattern в мапинге сервлета, фактически указывает на то, относительно какой директории можно будет получить доступ к RESTful сервисам нашего приложения. В данном случае это /webresources. Вы можете поменять этот параметр, если считаете нужным. Теперь рассмотрим подробнее класс веб-сервиса. Здесь есть 2 интересных момента: 1) Аннотация @Path("simpleservice") указанная для класса говорит о том что этот класс является реализацией RESTful веб-сервиса. Строковый параметр «simpleservice» задает относительный от указанного в url-pattern путь доступа к сервису. 2) Аннотация @GET указанная для метода public String firstMessage() говорит о том, что данный метод будет реагировать на HTTP GET запросы посланные по URL указывающему на этот сервис. После обработки GET запроса, метод вернет строку "This is a simple RESTful web service!". MIME type по умолчанию является text/plain, но его можно переопределить с помощью аннотации @Produces(). Шаг № 3 – Собрать и задеплоить. Выполните сборку проекта используя Maven:
В папке target проектa появится файл myrestfulapp.war. Разверните данное приложение на вашем сервлет-контейнере (например Tomcat). Осуществить доступ к приложению можно через любой http клиент. URL будет формироваться следующим образом:
У меня получился следующий путь после деплоя на Tomcat:
В результате запроса с помощью веб-браузера на экране должно появиться сообщение написанное жирным шрифтом: This is a simple RESTful web service! А теперь немного модернизируем сервис, добавив обработку параметров:
Пересоберем и задеплоим сервис заново. Выполним запрос используя следующий url:
Как должно быть видно из результата (Hello, Dude! This is a simple RESTful web service!), в метод firstMessage был успешно передан строковый параметр, заданный именем name. На этом я бы хотел завершить этот краткий обзор. Ну хотя бы для того, чтобы оставить материал для других статей на эту тему. А он уж поверьте есть. За бортом осталось очень много всякой вкуснятины: доступ к path и form и другим типам параметров, обработка post, put, delete, head запросов включая multi-part, написание своих провайдеров ресурсов, тонкое формирование ответов на запросы и многое другое. Так что если позволит время, то очередные статьи не за горами ;-) Ссылки на ресурсы используемые при написании статьи: https://jersey.dev.java.net/ - домашняя страница проекта Jersey. http://java.sun.com/developer/technicalArticles/WebServices/restful/ - обзор RESTful веб-сервисов на java.sun.com. http://jcp.org/en/jsr/detail?id=311 - спецификация JAX-RS 1.0. http://docs.sun.com/app/docs/doc/820-4867/6nga7f5mk?l=ru&a=view - руководство разработчика. |
| Автор: Foror 5.1.2009, 15:50 | ||
В tapestry5 можно просто создать страницу:
Ничего, никуда прописывать не надо. Просто вызывайте http://localhost:8080/myrestfulapp/simpleservice:firstmessage/Dude не принимайте близко к сердцу, я просто tapestry5 всячески пропогандирую |
| Автор: COVD 5.1.2009, 16:40 | ||
Для этого, на первый взгляд, простого GET запроса достаточно. Наверное тут нужно подробнее. PS. Кстати, в нетбинс 6.5 есть образцы NewProject -> Samples -> Web Services -> Hello World (RESTful), Customer Database (RESTful), Customer Database on Spring (RESTful). Пустой проект Hello World дает 6 мегабайтный war. |
| Автор: Andrey1 26.11.2009, 16:42 |
| Очень интересная статья! А как настраивать авторизацию к веб-сервису? И как потом работать (каким клиентом лучше авторизовываться)? |
| Автор: powerOn 26.11.2009, 17:43 | ||
Авторизацию можно настроить используя любой стандартный способ поддерживаемый веб-контейнерами: basic, digest, client certificate, form. Обращение к сервису идет по url, а на него можно наложить ограничения. Впрочем, ничто не мешает создать собственный механизм авторизации, принимать имя пользователя и пароль, хранить информацию о залогинином пользователе в сессии. Вопрос не совсем понятен... Вся работа идет по http протоколу. Клиент, конечно же, должен уметь по нему общаться, да и понимать интерфейсы вашего сервиса. |
| Автор: COVD 26.11.2009, 20:39 |
| На мой взгляд тут есть моменты которые важно акцентировать. Принципиальным моментом в REST является ограничение на набор действий с ресурсом. Их всего 4 (GET, PUT, POST и DELETE) и они совпадают с HTTP. Второй момент - имя ресурса явно указывается в адресе ( в примере powerOn выше это "simpleservice" ). Отсюда следует важная практическая перспектива: простейший REST сервис - это вэб приложение, которое называется по имени ресурса, и имеет один сервлет, обслуживающий 4 типа запросов. Часто достаточно одного GET. Поскольку это стандартные запросы HTTP, то и идентифицировать их можно стандартными способами, реализованными в сервлетах. Сколько ресурсов - столько же адресов и, соответственно, сервисов, т.е. приложений (ресурс1.war, ресурс2.war, ... ресурсN.war. Соответственно, доступны эти ресурсы по адресам http://host/resource1, http://host/resource2,...). Возможно, это предельный случай, подчеркивающий идею. Чем удобна схема "один ресурс - один сервис". Такие унитарные сервисы проще строить, создавать кластеры ( http://host1/resource1, http://host2/resource1, ... ). Это антипод некогда модному подходу ( в RPC ? ), когда запрос пересылается всегда по адресу контроллера типа http://host/app/goto?.., а контроллер перенаправляет запрос конкретному исполнителю после анализа параметров запроса из URL или данных ( SOAP сообщения, например), посланных методом POST. Еще важно, что REST не предполагает хранения клиентских состояний на сервере, т.е. сессии там вредны вообще говоря с точки зрения возможности создания кластеров. Стиль REST минималистичен (всего 4 команды), но органично согласуется с протоколом HTTP. |
| Автор: powerOn 26.11.2009, 22:01 |
| COVD, все верно, если вы хотите именно REST в том виде как его описывают на википедии и в других авторских источниках. Но это не всегда то что нужно - Jersey можно применить и в других, более простых, целях. Например гонять JSON данные между веб-страницей и сервером для AJAX вызовов (благо JSON рендеринг легко прикручивается). Jersey не обязывает писать код в каком-то определенном стиле, выбор всегда за вами. |
| Автор: COVD 26.11.2009, 23:17 |
| Мне показалось, что ваш материал посвящен все же RESTful сервисам, а не возможностям Jersey. На мой взгляд, эта концепция интересна не только способами реализации. И потому спасибо вам за тему. |
| Автор: powerOn 27.11.2009, 08:36 | ||
И о том и о сём И вам тоже спасибо за проявленный к теме интерес |
| Автор: Andrey1 27.11.2009, 13:09 | ||
У клиента должны быть включены куки, например, чтобы он автоматически не терял сессию. Поэтому и возникает вопрос, с помощью каких java-либ (например) можно работать с веб-сервисом. Только с помощью jersey-client или либ, которые реализуют некий стандарт? |
| Автор: powerOn 27.11.2009, 14:07 | ||
В стандартной библиотеке имеется поддержка куки, посмотрите в сторону http://java.sun.com/javase/6/docs/api/java/net/CookieManager.html. Если не из стандартных вещей, то можно воспользоваться Apache HTTPClient. |
| Автор: Andrey1 23.3.2010, 11:38 |
| Никто не встречал примера как сделать RESTful веб-сервис для Tomcat, к которому нужна авторизация? В примерах для Jersey есть пример HTTPS Client/Server для сервера Grizzly, но как сделать все тоже самое для TomCat еще не понятно. P.S. Все, вопрос отпал: понял, что предлагается использовать контейнерную авторизацию и/или использовать HTTPS протокол. |
| Автор: Samotnik 27.8.2010, 16:21 | ||
powerOn, у меня ошибко при запуске
что это ? |
| Автор: powerOn 27.8.2010, 16:24 |
Это значит, что не было найдено ни одного класса помеченного аннотацией @Path, в пакетах указанных параметром com.sun.jersey.config.property.packages. |
| Автор: Samotnik 27.8.2010, 16:33 |
| powerOn, и что теперь делать ? Добавлено через 10 минут и 1 секунду ах тыж блин. все понял |