Apache CXF 102 CXF with REST
前言
续上篇Apache CXF 101,摘抄部分REST概念性知识,以运行实例考察CXF对REST的支持。
目录
1 REST简介
2 工具
3 运行实例
内容
本Spike记录中内容,如无特别指出,均引用[1]。
1 REST简介
有两种实现Web Service的主要方式:SOAP(Simple Object Access Protocl)和REST架构风格(Representational State Transfer architecture style)。
用REST架构风格构建的服务(RESTful服务),用简单的XML等形式封装数据、通过HTTP传输数据。
与基于SOAP的服务开发方法相比,施加于服务开发者的技术负担更小,特别是服务只需发送和接收简单的XML消息时。
REST架构风格是关于资源的,资源是用URI(Uniform Resource Indicator)标识的表示(representation)。
资源可以是任意信息,例如Book、Order等。客户通过交换资源的表示来查询或更新URI标识的资源。
表示中包含以具体格式记录的实际信息,常见的格式有HTML/XML/JSON。客户通常可以指定它/他/她需要的表示。所有处理特定资源上的信息均包含于请求自身,使得交互是无状态的。
用REST架构风格原则构建的Web服务称为RESTful Web服务。RESTful Web服务可视为可通过URI标识的资源。RESTful Web服务用标准的HTTP方法(GET/POST…)暴露操作的集合。客户使用HTTP协议通过URI访问/调用这些方法。
RESTful Service URI example
http://cxf.spike.com/department/deptname/employee
GET 返回部门中雇员列表
POST 创建部门中雇员记录
DELETE 删除部门中雇员记录
JSR support
JAX-RS[2]
JAS-RS定义这些目标:
POJO为中心
JAX-RS API提供了一组注解和相关的类/接口,将POJO暴露为RESTful资源。
HTTP为中心
RESTful资源通过HTTP协议暴露,该规范提供了清晰的HTTP协议与相关的JAX-RS API中类、方法之间的映射。同时提供了如何匹配HTTP请求到资源类和方法的指南。
格式独立
该API提供了一种可插拔机制,该机制允许以标准的方式添加HTTP内容类型。
容器独立
用JAX-RS开发的应用应该可以运行于任意容器中。该规范定义了如何用JAX-RS API部署应用的标准机制。
Java企业版容器包含
该规范定义了RESTful资源如何宿于Java EE6容器和如何利用容器提供的功能。
JAX-RS的实现[3]
Apache CXF 开源的Web服务框架。
Jersey 由Sun提供的JAX-RS的参考实现。
RESTEasy JBoss的实现。
Restlet 由Jerome Louvel和Dave Pawson开发,是最早的REST框架,先于JAX-RS出现。
Apache Wink 一个Apache软件基金会孵化器中的项目,其服务模块实现JAX-RS规范
2 工具
Firefox插件:Poster(https://addons.mozilla.org/en-US/firefox/addon/poster/)
安装后工具位置

工具面板

用数据测试

结果呈现

3 运行实例
Book Shop Application
Functionality:
(1) Category CRUD
(2) Add Books to a Category
(3) Getting Books belongs to a Category
[1]中指出了(CXF) RESTful服务开发实践步骤
(1) 创建Request/Response的Java数据对象
(2) 绑定Request/Response对象
(3) 创建RESTful实现:创建实现类并用JAX-RS注解
(4) 服务单元测试
(5) 创建客户端,调用服务方法
(6) 将服务部署于容器中
(1) 创建Request/Response的Java数据对象
(2) 绑定Request/Response对象
两个JAXB绑定的pojo,JAXB是CXF默认的绑定方式
Book
package demo.restful.pojo;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Description: Book<br/>
* Date: 2014-5-12 下午10:54:16
*/
@XmlRootElement(name = "Book")
public class Book {
private String bookId;
private String bookISBNnumber;
private String bookName;
private String author;//one author only
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getBookISBNnumber() {
return bookISBNnumber;
}
public void setBookISBNnumber(String bookISBNnumber) {
this.bookISBNnumber = bookISBNnumber;
}
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;
}
@Override
public String toString() {
return "Book [bookId=" + bookId + ", bookISBNnumber=" + bookISBNnumber + ", bookName=" + bookName + ", author=" + author + "]";
}
}
Category
package demo.restful.pojo;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Description: Category<br/>
* Date: 2014-5-12 下午10:53:52
*/
@XmlRootElement(name = "Category")
public class Category {
private String categoryId;
private String categoryName;
private List<Book> books;
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
@Override
public String toString() {
return "Category [categoryId=" + categoryId + ", categoryName=" + categoryName + ", books=" + books + "]";
}
}
(3) 创建RESTful实现:创建实现类并用JAX-RS注解
CategoryService接口
package demo.restful.service;
import javax.ws.rs.core.Response;
import demo.restful.pojo.Category;
/**
* Description: Category Service Interface With Exception Handling<br/>
* Date: 2014-5-12 下午11:12:02
*/
public interface CategoryService {
public Category getCategory(String id);
public Response addCategory(Category category);
public Response deleteCategory(String id);
public Response updateCategory(Category category);
public Response addBooks(Category category);
public Response getBooks(String id);
}
CategoryService实现类
package demo.restful.service;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import demo.restful.data.CategoryDAO;
import demo.restful.pojo.Category;
/**
* Description: Category Service Implementation With Exception Handling<br/>
* Date: 2014-5-12 下午11:12:02
*/
@Path("/categoryservice")
@Produces({ "application/xml", "application/json" })
public class CategoryServiceImpl implements CategoryService {
private CategoryDAO categoryDAO;//wired
public CategoryDAO getCategoryDAO() {
return categoryDAO;
}
public void setCategoryDAO(CategoryDAO categoryDAO) {
this.categoryDAO = categoryDAO;
}
@GET
@Path("/category/{id}")
public Category getCategory(@PathParam("id") String id) {
System.out.println("getCategory called with category id: " + id);
Category cat = (Category) getCategoryDAO().getCategory(id);
if (cat == null) {
ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
builder.type("application/xml");
builder.entity("<error>Category Not Found</error>");
throw new WebApplicationException(builder.build());
} else {
return cat;
}
}
@POST
@Path("/category")
@Consumes({ "application/xml", "application/json" })
public Response addCategory(Category category) {
System.out.println("addCategory called");
Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId());
if (cat != null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
getCategoryDAO().addCategory(category);
return Response.ok(category).build();
}
}
@DELETE
@Path("/category/{id}")
public Response deleteCategory(@PathParam("id") String id) {
System.out.println("deleteCategory with category id : " + id);
Category cat = (Category) getCategoryDAO().getCategory(id);
if (cat == null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
getCategoryDAO().deleteCategory(id);
return Response.ok().build();
}
}
@PUT
@Path("/category")
public Response updateCategory(Category category) {
System.out.println("updateCategory with category id : " + category.getCategoryId());
Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId());
if (cat == null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
getCategoryDAO().updateCategory(category);
return Response.ok(category).build();
}
}
@POST
@Path("/category/book")
@Consumes({ "application/xml", "application/json" })
public Response addBooks(Category category) {
System.out.println("addBooks with category id : " + category.getCategoryId());
Category cat = (Category) getCategoryDAO().getCategory(category.getCategoryId());
if (cat == null) {
return Response.status(Status.NOT_FOUND).build();
} else {
getCategoryDAO().addBook(category);
return Response.ok(category).build();
}
}
@GET
@Path("/category/{id}/books")
@Consumes({ "application/xml", "application/json" })
public Response getBooks(@PathParam("id") String id) {
System.out.println("getBooks called with category id : " + id);
Category cat = (Category) getCategoryDAO().getCategory(id);
if (cat == null) {
return Response.status(Status.NOT_FOUND).build();
} else {
cat.setBooks(getCategoryDAO().getBooks(id));
return Response.ok(cat).build();
}
}
}
以内存中Map实现的DAO:服务支持类CategoryDAO
package demo.restful.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import demo.restful.pojo.Book;
import demo.restful.pojo.Category;
/**
* Description: Category DAO Stub Implementation<br/>
* Date: 2014-5-12 下午11:22:17
*/
public class CategoryDAO {
//category-id : category
private static Map<String, Category> categoryMap = new HashMap<String, Category>();
//category-id : books
private static Map<String, List<Book>> bookMap = new HashMap<String, List<Book>>();
static {
//Populate some static data
Category category1 = new Category();
category1.setCategoryId("001");
category1.setCategoryName("Java");
categoryMap.put(category1.getCategoryId(), category1);
Book book1 = new Book();
book1.setAuthor("Naveen Balani");
book1.setBookName("Spring Series");
book1.setBookId("001");
book1.setBookISBNnumber("ISB001");
Book book2 = new Book();
book2.setAuthor("Rajeev Hathi");
book2.setBookName("CXF Series");
book2.setBookId("002");
book2.setBookISBNnumber("ISB002");
List<Book> booksList = new ArrayList<Book>();
booksList.add(book1);
booksList.add(book2);
bookMap.put(category1.getCategoryId(), booksList);
}
public void addCategory(Category category) {
categoryMap.put(category.getCategoryId(), category);
}
//Add Books associated with the Category
public void addBook(Category category) {
bookMap.put(category.getCategoryId(), category.getBooks());
}
public List<Book> getBooks(String categoryId) {
return bookMap.get(categoryId);
}
public Category getCategory(String id) {
Category cat = null;
//Dummy implementation to return a new copy of category to
//avoid getting overridden by service
if (categoryMap.get(id) != null) {
cat = new Category();
cat.setCategoryId(categoryMap.get(id).getCategoryId());
cat.setCategoryName(categoryMap.get(id).getCategoryName());
}
return cat;
}
public void deleteCategory(String id) {
categoryMap.remove(id);
// Remove association of books
bookMap.remove(id);
}
public void updateCategory(Category category) {
categoryMap.put(category.getCategoryId(), category);
}
}
(4) 服务单元测试
因服务有灵活的部署方式,部署在Servlet容器中上一篇记录中已经有所说明,另一种方式是以常规应用程序直接运行在JVM中。
Server实现
Spring配置文件restapp.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="categoryService" class="demo.restful.service.CategoryServiceImpl">
<property name="categoryDAO">
<ref bean="categoryDAO" />
</property>
</bean>
<bean id="categoryDAO" class="demo.restful.data.CategoryDAO">
</bean>
</beans>
常量类
package demo.restful;
/**
* Description: 常量类<br/>
* Date: 2014-5-12 下午11:41:09
*/
public class Constants {
public static final String SERVICE_URL = "http://localhost:9000/";
}
Server
package demo.restful.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import demo.restful.Constants;
import demo.restful.pojo.Book;
import demo.restful.pojo.Category;
import demo.restful.service.CategoryService;
import demo.restful.service.CategoryServiceImpl;
/**
* Description: Server<br/>
* Date: 2014-5-12 下午11:37:09
*/
public class Server {
public static void main(String[] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "/demo/restful/restapp.xml" });
CategoryService categoryService = (CategoryServiceImpl) appContext.getBean("categoryService");
// Service instance
JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean();
restServer.setResourceClasses(Category.class, Book.class);
restServer.setServiceBean(categoryService);
restServer.setAddress(Constants.SERVICE_URL);
restServer.create();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server Stopped");
System.exit(0);
}
}
这样自然的,单元测试就有两种方法:部署在Servlet容器中的服务以浏览器/Poster测试,以常规应用程序部署的服务则可以编写JUnit单元测试。
Poster测试
这里用到的Poster的两个主要设置:
"Content to Send"label中将"Content Type"设置为application/xml(或application/json,视准备数据而定)
"Header"label中添加Name: Accept, Value: application/xml(或application/json)
新增Category


更新Category


JUnit单元测试
HTTPClient - 简单的服务客户端示例
package demo.restful.client;
import java.util.Iterator;
import org.apache.cxf.jaxrs.client.WebClient;
import demo.restful.pojo.Book;
import demo.restful.pojo.Category;
/**
* Description: HTTP Client<br/>
* Date: 2014-5-12 下午11:57:41
*/
public class HTTPClient {
public static void main(String[] args) {
WebClient client = WebClient.create("http://localhost:9000/");
Category category = client.path("categoryservice/category/001").accept("application/xml").get(Category.class);
System.out.println("Category details from REST service.");
System.out.println("Category Name " + category.getCategoryName());
System.out.println("Category Id " + category.getCategoryId());
System.out.println("Book details for Category " + category.getCategoryId() + " from REST service");
String bookString = "categoryservice/category/" + category.getCategoryId() + "/books";
WebClient clientBook = WebClient.create("http://localhost:9000/");
Category categoryBooks = clientBook.path(bookString).accept("application/xml").get(Category.class);
Iterator<Book> iterator = categoryBooks.getBooks().iterator();
while (iterator.hasNext()) {
Book book = iterator.next();
System.out.println("Book Name " + book.getBookName());
System.out.println("Book ISBN " + book.getBookISBNnumber());
System.out.println("Book ID " + book.getBookId());
System.out.println("Book Author " + book.getAuthor());
}
}
}
RESTCategoryService,测试媒体类型application/xml,为直观显示执行结果,未使用JUnit断言。
package demo.restful.client;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import demo.restful.pojo.Book;
import demo.restful.pojo.Category;
/**
* Description: RESTCategoryService in Servlet Container Unit test<br/>
* Date: 2014-5-13 下午9:41:27
*/
public class RESTCategoryServiceTest {
private WebClient client = null;
private static final String FORMAT = "application/xml";
private static String id = null;
@BeforeClass
public static void setUpBeforClass() {
id = newId();
}
@Before
public void setUp() {
client = WebClient.create("http://localhost:8082/CXF/");
}
@Test
public void getCategory() {
System.out.println("======================getCategory");
Category category = client.path("categoryservice/category/001").accept(FORMAT).get(Category.class);
System.out.println(category);
System.out.println("======================getCategory");
}
@Test
public void addCategory() {
System.out.println("======================addCategory");
Category category = new Category();
category.setCategoryId(id);
category.setCategoryName(".NET");
System.out.println("Add " + category + "...");
Category response = client.path("categoryservice/category").accept(FORMAT).type(FORMAT).post(category, Category.class);
System.out.println(response);
//test using query
System.out.println("Get category " + id + "...");
client = WebClient.create("http://localhost:8082/CXF/");//new WebClient!!!
System.out.println(client.path("categoryservice/category/" + id).accept(FORMAT).get(Category.class));
System.out.println("======================addCategory");
}
@Test
public void updateCategory() {
System.out.println("======================updateCategory");
Category category = new Category();
category.setCategoryId(id);
category.setCategoryName("Microsoft .NET");
Response response = client.path("categoryservice/category").put(category);
System.out.println(response.getStatus());
System.out.println(response.getEntity());
System.out.println("======================updateCategory");
}
@Test
public void addBooks() {
System.out.println("======================addBooks");
client.path("/categoryservice/category/book").type(FORMAT).accept(FORMAT);
Category cat = new Category();
cat.setCategoryId(id);
cat.setCategoryName("Fiction Series");
Book book1 = new Book();
book1.setAuthor("Naveen Balani");
book1.setBookId("NB001");
book1.setBookISBNnumber("ISBNB001");
book1.setBookName("Fiction Book1");
List<Book> booksList = new ArrayList<Book>();
booksList.add(book1);
cat.setBooks(booksList);
Category response = client.post(cat, Category.class);
System.out.println(response);
System.out.println("======================addBooks");
}
@Test
public void getBooks() {
System.out.println("======================getBooks");
Category category = client.path("/categoryservice/category/" + id + "/books").accept(FORMAT).get(Category.class);
System.out.println("Book details retreived from service with format " + FORMAT);
List<Book> books = category.getBooks();
for (Book book : books) {
System.out.println("Book Name " + book.getBookName());
System.out.println("Book ISBN " + book.getBookISBNnumber());
System.out.println("Book ID " + book.getBookId());
System.out.println("Book Author " + book.getAuthor());
}
System.out.println("======================getBooks");
}
@Test
public void deleteCategory() {
System.out.println("======================deleteCategory");
Response response = client.path("categoryservice/category/" + id).delete();
System.out.println(response.getStatus());
System.out.println("======================deleteCategory");
}
private static String newId() {
return UUID.randomUUID().toString().replaceAll("\\-", "").toUpperCase();
}
}
JSONRESTCategoryServiceTest,与RESTCategoryService基本相同,唯一的区别在于媒体类型为application/json
package demo.restful.client;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import demo.restful.pojo.Book;
import demo.restful.pojo.Category;
/**
* Description: JSONRESTCategoryService in Servlet Container Unit test<br/>
* Date: 2014-5-13 下午9:41:27
*/
public class JSONRESTCategoryServiceTest {
private WebClient client = null;
private static final String FORMAT = "application/json";
private static String id = null;
@BeforeClass
public static void setUpBeforClass() {
id = newId();
}
@Before
public void setUp() {
client = WebClient.create("http://localhost:8082/CXF/");
}
@Test
public void getCategory() {
System.out.println("======================getCategory");
Category category = client.path("categoryservice/category/001").accept(FORMAT).get(Category.class);
System.out.println(category);
System.out.println("======================getCategory");
}
@Test
public void addCategory() {
System.out.println("======================addCategory");
Category category = new Category();
category.setCategoryId(id);
category.setCategoryName(".NET");
System.out.println("Add " + category + "...");
Category response = client.path("categoryservice/category").accept(FORMAT).type(FORMAT).post(category, Category.class);
System.out.println(response);
//test using query
System.out.println("Get category " + id + "...");
client = WebClient.create("http://localhost:8082/CXF/");//new WebClient!!!
System.out.println(client.path("categoryservice/category/" + id).accept(FORMAT).get(Category.class));
System.out.println("======================addCategory");
}
@Test
public void updateCategory() {
System.out.println("======================updateCategory");
Category category = new Category();
category.setCategoryId(id);
category.setCategoryName("Microsoft .NET");
Response response = client.path("categoryservice/category").put(category);
System.out.println(response.getStatus());
System.out.println(response.getEntity());
System.out.println("======================updateCategory");
}
@Test
public void addBooks() {
System.out.println("======================addBooks");
client.path("/categoryservice/category/book").type(FORMAT).accept(FORMAT);
Category cat = new Category();
cat.setCategoryId(id);
cat.setCategoryName("Fiction Series");
Book book1 = new Book();
book1.setAuthor("Naveen Balani");
book1.setBookId("NB001");
book1.setBookISBNnumber("ISBNB001");
book1.setBookName("Fiction Book1");
List<Book> booksList = new ArrayList<Book>();
booksList.add(book1);
cat.setBooks(booksList);
Category response = client.post(cat, Category.class);
System.out.println(response);
System.out.println("======================addBooks");
}
@Test
public void getBooks() {
System.out.println("======================getBooks");
Category category = client.path("/categoryservice/category/" + id + "/books").accept(FORMAT).get(Category.class);
System.out.println("Book details retreived from service with format " + FORMAT);
List<Book> books = category.getBooks();
for (Book book : books) {
System.out.println("Book Name " + book.getBookName());
System.out.println("Book ISBN " + book.getBookISBNnumber());
System.out.println("Book ID " + book.getBookId());
System.out.println("Book Author " + book.getAuthor());
}
System.out.println("======================getBooks");
}
@Test
public void deleteCategory() {
System.out.println("======================deleteCategory");
Response response = client.path("categoryservice/category/" + id).delete();
System.out.println(response.getStatus());
System.out.println("======================deleteCategory");
}
private static String newId() {
return UUID.randomUUID().toString().replaceAll("\\-", "").toUpperCase();
}
}
(5) 创建客户端,调用服务方法
见HTTPClient示例。
(6) 将服务部署于容器中
上一篇记录中已经有所说明。
//FIXME need to add description about Servlet container delopyment descriptor and CXF-Spring Intergration configuarations
Servlet容器部署描述符web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>CXF</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/cxf-beans.xml
classpath:/demo/restful/restapp.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
CXF-Spring集成配置文件cxf-beans.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:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf-all.xml" />
<!-- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"
/> -->
<import resource="classpath:/demo/restful/restapp.xml" />
<jaxws:endpoint xmlns:tns="http://cxf.spike.com/" id="helloservice" implementor="com.spike.cxf.HelloServiceImpl"
wsdlLocation="wsdl/helloserviceimpl.wsdl" endpointName="tns:HelloServiceImplPort" serviceName="tns:HelloServiceImplService"
address="/HelloServiceImplPort">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
<jaxrs:server id="categoryRESTService" address="/">
<jaxrs:features>
<cxf:logging />
</jaxrs:features>
<jaxrs:serviceBeans>
<ref bean="categoryService" />
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
参考资料
[1]Balani N., Hathi R..Apache CXF web service development Develop and deploy SOAP and RESTful web service[M]. Birmingham: Packet Publishing. 2009.
[2]JSR311: JAX-RS: The JavaTM API for RESTful Web Services[EB/OL]. https://jcp.org/en/jsr/detail?id=311. 2014-05-12.
[3]JAX-RS. Wiki. http://zh.wikipedia.org/wiki/JAX-RS. 2014-05-12.
Apache CXF 102 CXF with REST的更多相关文章
- Apache CXF 103 CXF Basics - partial
本Spike记录中内容,如无特别指出,均引用[1]. 0 引言 0.1 基本的Web服务术语 XML 业界的结构化交换信息表示的事实上的标准. XML namespace是在XML文档中提供唯一的命名 ...
- WebService -- Java 实现之 CXF ( 使用CXF工具生成client 程序)
1. 下载CXF 工具解压到磁盘 2.添加工具bin目录到PATH环境变量 3.创建一个CXF client新项目 4. run -> cmd 到指定目录,并运行工具目录下的批处理 “wadl2 ...
- CXF之四 cxf集成Spring
CXF原生支持spring,可以和Spring无缝集成.WebService框架CXF实战一在Tomcat中发布WebService(二)通过Spring Web实现CXFServlet.下面将Spr ...
- Apache CXF实现Web Service(2)——不借助重量级Web容器和Spring实现一个纯的JAX-RS(RESTful) web service
实现目标 http://localhost:9000/rs/roomservice 为入口, http://localhost:9000/rs/roomservice/room为房间列表, http: ...
- Apache CXF 例子
来自:http://www.cnblogs.com/frankliiu-java/articles/1641949.html Apache CXF 是一个开放源代码框架,是在Xfire 跟Celtix ...
- JAVAEE——BOS物流项目07:WebService入门、apache CXF入门、基于CXF发布CRM服务
1 学习计划 1.WebService入门 n 什么是WebService n 调用网络上的WebService服务 n SOAP和WSDL概念 n 基于JDK1.7发布一个简单的WebService ...
- Apache cxf暴露接口以及客户端调用之WebService初步理解
在我们真实的项目中,经常会调用别人提供给我们的接口,或者在自己的团队中, restful风格的前后端分离也经常会提供一个后端接口暴露出去供app,或者.net/C/C++程序员去调用,此时就需要使用到 ...
- Web Service与Apache CXF 框架
一.WebService简介 为了支持跨网络的机器间相互操作交互而设计,用于开发分布式的互操作的应用程序组件. Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执 ...
- apache CXF quickstart
1下载 官网: cxf.apache.org 下载 CXF 的开发包: 解压上面的 zip 文件 : 2介绍 1什么是cxf Apache CXF™ is an open source service ...
随机推荐
- 解决visualsvn监听ip 错误的问题
系统重启+休眠之类的,弄几次,莫名其妙的svn就连接不上了, 有时候启动不起,有时候是启动连接不上,发现监听的ip错了 TCP [::]:443 [::]:0 ...
- HDU 4906 Our happy ending(2014 Multi-University Training Contest 4)
题意:构造出n个数 这n个数取值范围0-L,这n个数中存在取一些数之和等于k,则这样称为一种方法.给定n,k,L,求方案数. 思路:装压 每位 第1为表示这种方案能不能构成1(1表示能0表示不能) ...
- 二模 (7) day2
第一题: 题目大意:多重背包. 解题过程: 1.二进制拆分.最慢的点0.5s. 2.单调队列优化会更快,不过我不会.. 第二题: 题目描述:给定一个n×m的矩阵,记录左上角为(1,1),右下角为(n, ...
- C#如何以管理员身份运行程序
在使用winform程序获取调用cmd命令提示符时,如果是win7以上的操作系统,会需要必须以管理员身份运行才会执行成功,否则无效果或提示错误. 比如在通过winform程序执行cmd命令时,某些情况 ...
- ASP.Net Chart Control -----Bar and Column Charts
StackedBar StackedColumn StackedArea <asp:CHART id="Chart1" runat="server" H ...
- bitset常用函数用法记录 (转载)
有些程序要处理二进制位的有序集,每个位可能包含的是0(关)或1(开)的值.位是用来保存一组项或条件的yes/no信息(有时也称标志)的简洁方法.标准库提供了bitset类使得处理位集合更容易一些.要使 ...
- Rhel6-haproxy+keepalived配置文档
系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.119:haproxy,keepalived server19.exa ...
- 2013年7月份第1周51Aspx源码发布详情
启睿网络信息服务器实例源码 2013-7-5 [ VS2005 ]功能介绍:睿网络信息服务器,QiRui Net Information Services简称QRNIS,该软件前身系KCIS.当前版 ...
- python视频教程:十分钟快速入门python
想要学习python这门语言,却始终找不到一个全面的Python视频教程,倘若你是真心想学好一门语言,小编建议你亲自动手实践的.下面来看看入门python的学习教程. Python的语言特性 Pyth ...
- 修复win8引导
格式化那个350MB的分区(Win8安装盘启动之后挂载在c:之后,用Win8的安装U盘,进去修复模式,然后进入高级选项的命令行提示符模式.接着,转到安装现有Win8的分区(Win8安装盘启动之后挂载在 ...