Вступление
Как вы уже знаете, есть два способа разработки веб-сервиса
- Простой протокол доступа к объектам (SOAP)
 - Представительный государственный трансферт (REST)
 
Прежде чем приступить к созданию веб-службы на основе REST с использованием Apache CXF, посмотрим, что такое REST. REST — это не технология и, конечно, не какой-то стандарт. Это просто архитектурный стиль, который описывает, как написать веб-сервис определенным образом. Этот стиль был определен неким Роем Филдингом (кольцевые колокольчики? Да, вы правильно догадались, он один из архитекторов HTTP) в 2000 году. Главный герой архитектуры REST — это Ресурс, который может быть уникально идентифицирован с помощью Унифицированного идентификатора ресурса или URI . Состояние ресурса в любой данный момент времени представлено документом и называется представлением ресурса. Клиент может обновить состояние ресурса, передав представление вместе с запросом. Новое представление теперь возвращается клиенту вместе с ответом. Представление содержит информацию в таких форматах, как html, xml, JSON и т. Д., Которые принимаются ресурсом. Ресурс, который придерживается правил архитектуры REST, называется ресурсом RESTfull, а веб-сервис, который придерживается этого правила, называется веб-сервисом RESTfull.
Создайте проект, содержащий ваш веб-сервис
Я обычно делаю свою веб-разработку в struts2 + spring, используя maven Strut2 стартовый архетип для создания своего веб-проекта. Чтобы использовать CXF в моем проекте, я добавляю следующие зависимости к своему POM
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
 | 
<dependency>    <groupId>org.apache.cxf</groupId>    <artifactId>cxf-rt-frontend-jaxws</artifactId>    <version>${cxf.version}</version></dependency><dependency>    <groupId>org.apache.cxf</groupId>    <artifactId>cxf-rt-transports-http</artifactId>    <version>${cxf.version}</version></dependency><dependency>    <groupId>org.apache.cxf</groupId>    <artifactId>cxf-rt-transports-http-jetty</artifactId>    <version>${cxf.version}</version></dependency> | 
Пользователи не maven могут найти подробности зависимостей, которые будут добавлены по следующей ссылке: http://cxf.apache.org/docs/using-cxf-with-maven.html . CXF можно скачать прямо здесь: http://cxf.apache.org/download.html
Как создать веб-сервис CXF RESTfull?
Предположим, вы хотите создать веб-сервис RESTfull, используя CXF для управления книгами на вашей личной книжной полке. Как правило, вы хотите выполнить следующие действия на книжной полке
- Добавить книгу
 - Обновить информацию о книге
 - Удалить книгу с полки
 - Получить книгу
 - Получить список книг
 - Получить список книг по имени автора
 
Следующие шаги необходимы для создания такого сервиса
- Создайте BookVO, BookList (объект значения) для передачи в виде представления в запросе и ответе.
 - Свяжите объекты с запросом и ответом.
 - Создайте класс реализации службы для принятия запроса и генерации ответа.
 - Регистрация вашего веб-сервиса с контейнером CXF.
 - Разверните сервис в веб-контейнере.
 - Создайте клиентов для вызова методов в службе.
 
Получение исходного кода для этого урока
Я передал исходные файлы для этого урока в SVN.
- Вы можете загрузить веб-приложение по адресу: http://subversion.assembla.com/svn/weblog4j/Weblog4jDemo/trunk
 - Вы можете скачать клиент с: http://subversion.assembla.com/svn/weblog4j/DemoClient/trunk
 
Примечание. Оба проекта являются проектами ItelliJ maven, поэтому вы можете напрямую импортировать их в вашу среду IntelliJ или скопировать файлы вручную в другую среду IDE.
Создать BookVO (объект значения) для передачи в качестве представления в запросе и ответе.
Класс BookVO
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
 | 
package com.aranin.weblog4j.vo;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;import java.io.Serializable;@XmlRootElement(name="Book")public class BookVO implements Serializable{private long bookId;private String bookName;private String author;public long getBookId() {return bookId;}public void setBookId(long bucketId) {this.bookId = bookId;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}} | 
Класс BookList
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
 | 
package com.aranin.weblog4j.vo;import javax.xml.bind.annotation.XmlRootElement;import java.util.ArrayList;import java.util.List;@XmlRootElement(name="BookList")public class BookList {private List<BookVO> bookList;public List<BookVO> getBookList() {if(bookList == null){bookList = new ArrayList<BookVO>();}return bookList;}public void setBookList(List<BookVO> bookList) {this.bookList = bookList;}} | 
Привязать объект данных, т.е. BookVO с запросом и ответом
Чтобы связать BookVO с запросом или ответом, его необходимо сериализовать в потоки XML или JSON. Сериализация должна выполняться с использованием одного из компонентов привязки данных. CXF использует JAXB для компонента привязки данных по умолчанию. JaXB использует аннотацию @XmlRootElement для сопоставления объекта данных с xml. Вы можете увидеть использование аннотации XmlRootElement в приведенном выше коде.
Создайте класс реализации сервиса для принятия запроса и генерации ответа.
Давайте посмотрим, как выглядит веб-сервис CXF RestFull. Мы создадим класс BookService, который будет выполнять операции добавления, обновления, удаления и получения на BookSelf.
Класс BookService
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
 | 
package com.aranin.weblog4j.services.rest;import com.aranin.weblog4j.hashdb.HashDB;import com.aranin.weblog4j.vo.BookVO;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.ws.rs.*;import javax.ws.rs.core.Response;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;/** * Created by IntelliJ IDEA. * User: Niraj Singh * Date: 3/13/13 * Time: 3:58 PM * To change this template use File | Settings | File Templates. */public class BookService {protected final Logger log = LoggerFactory.getLogger(BookService.class);    @POST    @Path("/getbook/{name}")    @Produces({"application/xml","application/json"})    @Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})    public Response getBucket(@PathParam("name") String name) {        log.debug("name : " + name);        BookVO bookVO = null;        try {            bookVO = HashDB.getBook(URLDecoder.decode(name, "UTF-8"));        } catch (UnsupportedEncodingException e) {            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.        }        if(bookVO == null){            return Response.status(Response.Status.BAD_REQUEST).build();        }else{            return Response.ok(bookVO).build();        }    }    @POST    @Path("/addbook")    @Produces({"application/xml","application/json"})    @Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})    public Response addBook(@FormParam("name") String bookName,                            @FormParam("author") String author) {        log.debug("inside addBook");        BookVO bookVO = new BookVO();        bookVO.setBookName(bookName);        bookVO.setAuthor(author);        HashDB.insertBook(bookVO);        if(HashDB.getBook(bookName) == null){            return Response.status(Response.Status.BAD_REQUEST).build();        }else{            return Response.ok(bookVO).build();        }    }} | 
Вы можете увидеть два метода в классе BookService getBook и addBook. Это сервисные методы для получения и добавления книги. Остальные методы удаления обновлений и т. Д. Могут быть написаны таким же образом. Теперь давайте посмотрим, что означают различные аннотации и вызов метода.
- @POST — это означает, что сервис получает только POST-запрос.
 - @Path — это путь к веб-сервису. Таким образом, веб-сервис может быть вызван с использованием следующего Url <base_url> / bookservice / getbook / {name} для выборки, <base_url> / bookservice / addbook для добавления.
 - @Produces — указывает тип сгенерированного ответа MIME. В нашем случае это и приложение / xml, и приложение / json.
 - @Consumes — указывает MIME-тип запроса, который может использовать этот сервис.
 
Регистрация вашего веб-сервиса с контейнером CXF.
Одна из замечательных особенностей CXF заключается в том, что он использует конфигурацию на основе пружины для регистрации своих конечных точек веб-службы, поэтому давайте создадим beans.xml в WEB-INF и настроим CXF в web.xml. Для этого сначала нам нужно подключить файл beans.xml для загрузки контейнером Spring.
| 
 1 
2 
3 
4 
 | 
<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/beans.xml,/WEB-INF/applicationContext.xml</param-value></context-param> | 
Во-вторых, загрузите реестр CXFServlet в web.xml.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
 | 
<servlet><servlet-name>CXFServlet</servlet-name><display-name>CXF Servlet</display-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><load-on-startup>2</load-on-startup></servlet><servlet-mapping><servlet-name>CXFServlet</servlet-name><url-pattern>/*</url-pattern></servlet-mapping> | 
Теперь откройте ваш bean.xml и зарегистрируйте конечную точку книжного сервиса.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
 | 
<?xml version="1.0" encoding="UTF-8"?>    xsi:schemaLocation="    <import resource="classpath:META-INF/cxf/cxf.xml" />    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />    <jaxws:endpoint      id="bookShelfService"      implementor="com.aranin.weblog4j.services.BookShelfServiceImpl"      address="/bookshelfservice" />    <bean id="bookserviceclass" class="com.aranin.weblog4j.services.rest.BookService"/>    <jaxrs:server id="bookservice" address="/bookservice">        <jaxrs:serviceBeans>        <ref bean="bookserviceclass" />        </jaxrs:serviceBeans>    </jaxrs:server></beans> | 
Теперь ваш веб-сервис готов. Создайте свое веб-приложение и разверните его в любом контейнере сервлетов.
Создание клиента для вашего веб-сервиса
Клиенты могут быть созданы разными способами, я использовал Apache Http Components для написания своего клиента. Библиотеки можно найти по адресу http://hc.apache.org/httpclient-3.x/ .
Пользователь Maven может вытащить банку компонентов Http, используя следующие
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
 | 
<dependency><groupId>commons-httpclient</groupId><artifactId>commons-httpclient</artifactId><version>3.1</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.1.3</version><scope>compile</scope></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.1.3</version><scope>compile</scope></dependency> | 
Теперь, чтобы вызвать веб-сервис, я создал класс утилит под названием DemoRestClient.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
 | 
package com.aranin.weblog4j.client;import com.aranin.weblog4j.vo.BookVO;import org.apache.commons.httpclient.Header;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.methods.PostMethod;import java.net.URLEncoder;/** * Created by IntelliJ IDEA. * User: Niraj Singh * Date: 3/13/13 * Time: 4:15 PM * To change this template use File | Settings | File Templates. */public class DemoRestClient {    public static void main(String[] args){        DemoRestClient restClient = new DemoRestClient();        try {            //restClient.addBook("Naked Sun", "Issac Asimov");            restClient.getBook("Naked Sun");        } catch (Exception e) {            e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.        }    }    public BookVO getBook(String bookName) throws Exception {        String output = null;        try{            url = url + URLEncoder.encode(bookName, "UTF-8");            HttpClient client = new HttpClient();            PostMethod mPost = new PostMethod(url);            client.executeMethod( mPost );            Header mtHeader = new Header();            mtHeader.setName("content-type");            mtHeader.setValue("application/x-www-form-urlencoded");            mtHeader.setName("accept");            mtHeader.setValue("application/xml");            mPost.addRequestHeader(mtHeader);            client.executeMethod(mPost);            output = mPost.getResponseBodyAsString( );            mPost.releaseConnection( );            System.out.println("out : " + output);        }catch(Exception e){            throw new Exception("Exception in retriving group page info : " + e);        }        return null;    }    public void addBook(String bookName, String author) throws Exception {        String output = null;        try{            HttpClient client = new HttpClient();            PostMethod mPost = new PostMethod(url);            mPost.addParameter("name", "Naked Sun");            mPost.addParameter("author", "Issac Asimov");            Header mtHeader = new Header();            mtHeader.setName("content-type");            mtHeader.setValue("application/x-www-form-urlencoded");            mtHeader.setName("accept");            mtHeader.setValue("application/xml");            //mtHeader.setValue("application/json");            mPost.addRequestHeader(mtHeader);            client.executeMethod(mPost);            output = mPost.getResponseBodyAsString( );            mPost.releaseConnection( );            System.out.println("output : " + output);        }catch(Exception e){        throw new Exception("Exception in adding bucket : " + e);        }    }} | 
Запустите этот клиент, чтобы увидеть выходные данные вашего веб-сервиса. Прямо сейчас он отправит xmloutput, поскольку заголовок подтверждения ответа — «application / xml». Вы можете изменить его на application / json, чтобы получить вывод json.
Это все люди. Это очень простое введение в разработку веб-сервиса RestFull с использованием apache CXF, есть еще много чего, что можно исследовать. Счастливого пути, до свидания. Пожалуйста, оставьте некоторые комментарии, и если вы прочитаете это, чтобы вдохновить меня.