Сегодня будем поднимать простое CXF приложение, которае выводит в браузере простое сообщение test Servlet.
Для этого нам потребуется:
- JDK
- Tomcat
- Библиотеки поддерживающие cxf. Скачайте архив, распакуйте его и просто закиньте каталог lib в корень проекта, ссылку найдете чуть ниже
- Командная строка, где мы будем запускать shell скрипт, который мы напишем сами
Проект собирается в линуксе, по крайней мере у меня shell скрипт под линукс, но кто хочет может все это дело собрать в и windows, только тогда свой батник подставьте. Вот готовый war архив если кто хочет сразу его положить в контейнер сервлетов и запустить:
А исходники лежат на гитХабе: https://github.com/dev-blogs/cxfServlet
Мы не будем использовать всякие сборищки такие как maven или gradle. Позднее когда научимся подниматься с помощью shell скрипта, проделаем тоже самое только уже с использованием сборщиков. Необходимость компилировать и запустить наш пример без использования спец средств вызвана тем, чтобы понимать что происходит на всех этапах лайфсайкла разработки, что касается maven и пр, все это конечно же надо особенно не для таких тривиальных приложение как хэлоу ворлд, но сначала, научимся все это собирать вручную 😉
0. Структура приложения
Создадим каталог cxfServlet и в нем создадим вот такую структуру приложения:
CXFServlet ├──src │ └──service │ ├──TestService.java │ └──impl │ └──TestServiceImpl.java ├──WEB-INF │ ├──web.xml │ └──spring │ └──spring-servlet.xml ├──resources ├──lib └──build.sh
Потом, когда мы добавим все необходимые java файлы и запустим build.sh скрипт, в текущем каталоге появится каталог build, в котором компилятор создаст всю структуру пакетов и разложит по ним каждый класс, а в корне структуры появится war архив готовый для деплоя на сервер:
build ├──WEB-INF │ ├──classes │ │ └──service │ │ ├──TestService.class │ │ └──impl │ │ └──TestServiceImpl.class │ ├──spring │ │ └──spring-servlet.xml │ ├──lib │ └──web.xml └──cxfServlet.war
1. Добавляем java код
Java код будет очень примитивным, чтобы не усложнять задачу разными свистелками, а сконцентрироваться на том, как это все дело связать спрингом.
И так, добавляем java интерфейс который будет сервисом. Еще раз повторю, я не создаю в каталоге src всю структуру пакетов методом создания каталогов правой кнопкой мыши, это сделает за меня javac при компиляции кода в каталог build.
TestService.java
package service; import javax.ws.rs.GET; import javax.ws.rs.Path; @Path("/test-service/") public interface TestService { @GET @Path("/test") public String execute(); }
и имплементацию интерфейса
TestServiceImpl.java
package service.impl; import service.TestService; public class TestServiceImpl implements TestService { public String execute() { return "test Servlet"; } }
2. Связываем все компоненты вместе с помощью Spring
После того, как java классы созданы, добавляем в корень проекта каталог WEB-INF, куда поместим web.xml и spring-context.xml.
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>RestDemo</display-name> <description>RestDemo</description> <!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/spring/spring-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF --> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
Добавляем в каталоге WEB-INF каталог spring, и добавляем контекст спринга
spring-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <bean id="serviceBean" class="service.impl.TestServiceImpl"> </bean> <jaxrs:server id="restController" address="/"> <jaxrs:serviceBeans> <ref bean="serviceBean"/> </jaxrs:serviceBeans> </jaxrs:server> </beans>
3. Библиотеки CXF
Для того, чтобы компилятор знал про существование необходимых классов для работы CXF, нужны соответствующие библиотеки.
Скачайте архив с библиотеками, извлеките из него каталог lib и положите его в корень проекта
4. Build script
И последнее что нам осталось сделать это написать билд скрипт. Собирать будем в системе линукс, поэтому тот кто на винде переделайте этот скрипт в батник.
PATH_TO_DEPLOY=/path/to/your/servlet_container PROJECT_NAME=cxfServlet # Удаляем каталог с предыдущим билдом if test -d build; then rm -rf build fi # Создаем новый каталог, куда будем помещать билд mkdir build # Копируем туда заранее заготовленный каталог WEB-INF c web.xml cp -r WEB-INF build mkdir build/WEB-INF/classes # Компилируем проект в каталог build/WEB-INF/classes javac -d build/WEB-INF/classes -cp .:lib/* $(find src/* | grep .java) # Копируем все необходимые для CXF библиотеки в build/WEB-INF cp -r lib build/WEB-INF # Переходим в каталог build cd build # Создаем war архив jar cvf $PROJECT_NAME.war WEB-INF # war архив создан и готов для деплоя # Удалим из каталога контейнера webapps предыдущее приложение (и варник тоже) # переходим в корневой каталог приложения cd .. # запоминаем корневой каталог приложения HOME_PROJECT=`pwd` cd $PATH_TO_DEPLOY if test -d $PROJECT_NAME; then rm -rf $PROJECT_NAME fi if test -d $PROJECT_NAME.war; then rm -rf $PROJECT_NAME.war fi # Возвращаемся в каталог с новым билдом cd $HOME_PROJECT/build # Собсно деплой cp $PROJECT_NAME.war $PATH_TO_DEPLOY cd ..
Заключение
Если после запуска билд скрипта все пройдет без ошибок, то поздравляю, проект успешно собран и за деплоен в контейнер сервлетов. Осталось запустить контейнер сервлетов и ввести в строке адреса браузера URL: http://localhost:8080/cxfServlet/rest/test-service/test и вы должны увидеть текст «test Servlet».
Если же что-то пошло не так, то проверьте переменные в билд скрипте, возможно что-то не так с путями.
В следующем посте проделаем все тоже самое только с помощью maven.
Линки
http://www.ibm.com/developerworks/ru/library/j-jws12 — Web-сервисы Java: Знакомимся с CXF
http://cxf.apache.org/docs/writing-a-service-with-spring.html — сайт apache CXF
http://www.mkyong.com/maven/how-to-create-a-web-application-project-with-maven — блог How To Create A Web Application Project With Maven
http://sushantworld.wordpress.com/2011/01/23/apache-cxf-restful-web-service — Apache CXF to create rest web service
http://www.27programs.com/2013/11/09/building-restful-web-services-apache-cxf-spring — Building RESTful Web services with Apache CXF and Spring
http://www.ibm.com/developerworks/ru/library/j-jws12 — Web-сервисы Java: Знакомимся с CXF
http://www.javacodegeeks.com/2013/07/developing-restful-services-using-apache-cxf.html — Developing RESTful Services using Apache CXF