`
reymont
  • 浏览: 529440 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用CXF开发RESTFul服务

    博客分类:
  • CXF
 
阅读更多

 相信大家在阅读

CXF官方文档(http://cxf.apache.org/docs/index.html)时,总是一知半解。这里向大家推荐一本PacktPub.Apache.CXF.Web.Service.Development。目前,这本书是没有中文版的,为此笔者简单的写了一些经验总结。

CXF官方文档(http://cxf.apache.org/docs/index.html)时,总是一知半解。这里向大家推荐一本PacktPub.Apache.CXF.Web.Service.Development。目前,这本书是没有中文版的,为此笔者简单的写了一些经验总结。

 

 

 

这本书内容上安排的比较浅显,语言上也没有什么深奥的,值得一读。另外值得一提的是,这本书比官方文档高明之处是每个概念就介绍得很清楚,像第二章的Code-firstContract-first,第5章的FeatureInterceptor概念的介绍,还有第6章的REST概念简介,内容上都比官方文档详细很多。缺点就是并没有将CXF所有的特性都写下来,这就需要将samples中的内容好好消化一下了。

 

代码使用Maven组织

 

http://dl.iteye.com/topics/download/fbbf344b-2357-33fe-86d7-a44116e6de85

 

使用CXF开发RESTFul服务

在各个系统交互领域,Web services逐渐成为主流。有两种主要方式来开发Web ServicesSimple Object Access Protocol (SOAP)Representational State Transfer (REST)

 

开发基于SOAPWeb Services需要很多的约束, 以便客户端和服务端交互信息,例如,使用Web Service Description Language (WSDL)来描述信息。还有很多WS的标准如WS-Security

 

使用REST构架的服务被称为RESTful服务。这种架构利用简单的XMLHTTP协议上,就像网页一样发送请求,简化了基于SOAP架构开发。RESTful Web Services尤其适用于只需要提交和接受简单的XML信息。

 

接下来会介绍使用CXF框架来开发RESTful风格的Web Services

 

简介

Java API for RESTful services

CXF JAX-RS实现

开发RESTful服务

 

简介

 

REST也就是Representational State TransferREST并不特指一种技术,也不是一个标准,它仅仅是一个构架风格。REST 指的是一组架构约束条件和原则。满足这些约束条件和原则通过网络暴露资源给用户。事实上,WWW就是经典的REST架构风格。在服务器端,应用程序状态和功能可以分为各种资源。它向客户端公开。每个资源都使用 URI (Universal Resource Identifier) 得到一个惟一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GETPUTPOST DELETE。客户端通过交换各种资源的表现体来查询或更新资源。资源的表现体包括HTMLXMLJSON等。客户端需要解析响应服务器的表现体。客户端和服务器之间的交互在请求之间是无状态的,无状态请求可以由任何可用服务器应答。

 

下面是一些RESTfu例子,提供雇员和部门的信息,并介绍客户端怎样访问这些服务

 

URI for the RESTful service—http://<host>/department/deptname/employee:

     GET—获得deptname部门的所有员工信息

     POST—deptname部门创建员工信息。

     DELETE—删除 deptname部门一名员工信息

URI for the RESTful service—http://<host>/department/deptname/employee/naveen:

     GET—获得deptname部门名叫naveen的员工信息

     PUT—deptname部门创建名叫naveen的员工信息

     DELETE—删除deptname部门名叫naveen的员工信息

 

下面是POST请求的例子http://<host>/department/deptname/employee

 

 

POST /department/deptname/employee HTTP/1.1

Content-Type: */*

Accept: application/xml

User-Agent: Apache CXF 2.2.2

Cache-Control: no-cache

Pragma: no-cache

Host: 127.0.0.1:9001

<employee><firstname>rajeev</firstname><lastname>hathi</lastname>

<dob>10/26/78</dob></employee>

 

Java API for RESTful services

 

上一节,我们了解雇员POST请求。如果需要提供一种实现去识别雇员POST请求,我们应该做如下工作:

 

识别这是否一个HTTP POST请求。

HTTP POST请求中的XML的内容转换为实现端所需要的格式,例如JAVA对象。

执行指定的操作,例如插入雇员信息到数据库。

HTTP形式响应客户端,例如设置标志响应成功的HTTP状态200 ,并将响应转换到指定格式(XMLJSON),最后将其设置到HTTP Body

 

依据需求,可能你要实现所有的HTTP方法,如GETPUTDELETE等。这不就是标准的RESTful JAVA开发模式吗?接着,Java API for RESTful Web services (JAX-RS)规范制定了开发RESTful的标准。

 

JAX-RS规范定义了创建RESTful服务的语法。JAX-RS使用annotations注解在实现RESTful的服务,使用annotations注解POJO将它暴露为RESTful资源。RESTful服务类中,通过URI/category)和HTTPGET, POST)方法注解方法。

 

@GET

       @Path("/category/{id}")

       public Category getCategory(@PathParam("id") String id)

 

实现JAX-RS的框架在运行的时候,通过映射HTTP请求到RESTful方法,负责调用正确的JAVA实现方法。JAX-RS规范提供这种映射的方法的算法。基础算法包括,判断JAVA资源类,判断HTTP URI请求,判断内容格式(例如application/xml),还有HTTP方法(例如GET

 

JAX-RS规范提出如下要点:

 

POJO依赖性

为了暴露为资源,使用annotations注解POJO

 

HTTP依赖性

RESTful资源暴露在HTTP中,规范中将HTTP 协议和JAX-RS API相对应映射。

 

格式独立性

API中提供嵌入式的方法,标准化添加HTTP内容的类型。例如,application/xml就是HTTP内容的类型中的一种。

 

容器独立性

可以在任何一种容器中部署实现JAX-RS规范的应用程序。

 

 

 

CXF JAX-RS实现

 

CXF实现了JAX-RS1.0规范,并提供了很多特性帮助开发者搭建企业级的RESTful服务。

 

下面是CXF框架提供创建RESTful服务的各种特性。

 

 

集成Spring

Spring框架已经变成事实上的构建企业级JAVA应用程序集成框架。CXF提供与Spring整合,简化了配置和部署RESTful应用程序。Spring提供依赖注入促进松散耦合,提供各种服务,像声明式事务管理。所有这些Spring提供的特性都可以被开发RESTful服务的CXF框架使用。

 

插入式数据绑定

数据库绑定就是映射HTTP请求,例如JSONXML,到对应的JAVA对象。同样的,在发送HTTP响应之前,服务端的JAVA实现需要映射为客户端所需要的格式。通过提供数据库绑定组件,CXF在后台透明的处理映射。CXF支持各种数据绑定机制,如JAXBJSONXMLBeanAegisCXF允许指定特定的绑定机制。

 

客户端API

JAX-RS规范并没有提供客户端调用REST服务的APICXF提供了这种API直接调用RESTful服务,也可以使用Spring框架配置到应用程序中。

 

安全

CXF可以使用Spring框架集成的声明式安全组件,按照应用程序的需要限制资源类和方法,而不必使用代码处理安全性问题。

 

过滤器

过滤器用来预处理或后处理信息。CXF可以创建和配置过滤器来审核信息,记录信息的日志,还有基于应用要求修改请求或响应。

 

 

 

CXF也运行开发者使用JAX-WS ProviderDispatch API来创建RESTful服务。

 

开发RESTful服务

 

本节将介绍使用JAX-RS实现的方法来开发RESTful服务,并执行CRUD操作。首先看一下Book Shop应用。

 

Book Shop应用是一款网络应用,提供技术书籍(JAVA.NET)的分类。Book Shop让管理员为新的书籍创建分类,修改分类等。一旦这个分类存在,应用可以为这个分类添加新的书籍。

 

这个应用将提供如下方法:

创建分类

更新分类

删除分类

获取分类列表

获取特定分类

为特定分类添加书籍

获取特定分类中所有书籍

 

 

为了开发RESTful服务,需要做如下工作:

 

创建POJO

POJO类提供数据绑定

创建实现RESTful功能的服务类

创建调用RESTful服务的客户端

 

创建POJO

 

package demo.restful;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Book")
public class Book {

	private String bookId;
	
	private String bookISBNnumber;
	
	private String bookName;
	
	//Let assume one author only
	private String author;

	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;
	}
	
}

 

package demo.restful;

import java.util.Collection;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Category")
public class Category {

	private String categoryId;

	private String categoryName;

	private Collection<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 Collection<Book> getBooks() {
		return books;
	}

	public void setBooks(Collection<Book> books) {
		this.books = books;
	}

}

 

 

 

 

POJO类提供数据绑定

 

为了提供RESTful服务端和客户端通信,POJO需要转换为特定的格式,例如XMLJSON。为了实现这部分功能,需要一个数据绑定的组件来映射JAVA对象和XML(或者指定的格式)。

 

CXF使用JAXB作为默认的数据绑定组件。JAXB使用注解来定义JAVA对象和XML之间映射的关系。

 

POJOCategory中,注解@XmlRootElement指定CategoryXML的根元素。Category类的属性默认指定映射为@XmlElement@XmlElement用来定义XML中的子元素。@XmlRootElement@XmlElement允许自定义命名空间和XML中元素的名称。如果没有定义的话,JAXB在运行的时候默认的使用同样的属性名和类名来定义XML元素。

 

下面的XML请求表示了Category数据对象。

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

   <Category>

      <books>

         <author>Naveen Balani</author>

         <bookISBNnumber>ISBNB001</bookISBNnumber>

         <bookId>NB001</bookId>

         <bookName>Fiction Book1</bookName>

      </books>

      <categoryId>005</categoryId>

      <categoryName>Fiction Series</categoryName>

   </Category>

 

 

创建实现RESTful功能的服务类

 

类注解

 

CategoryService的类声明上定义了@Path @Produces注解。@Path定义了URI路径,客户端可以通过这个路径访问到CategoryService对象。如@Path("/categoryservice"),那么URI请求,就可以是http://localhost:9000/categoryservice/@Produces定义了服务类和方法生产内容的类型。如@Produces("application/xml"),那么CategoryService只会生产application/xml

 

方法注解

 

每个方法都和@Produces相关,它决定了这个方法生产什么样的响应。每个方法都有和HTTP方法映射的的注解,例如@GET @POST。方法中的@Path注解指定了该方法的URI。例如getCategory()方法上的@Path("/category/{id}"),可以使用http://localhost:9000/categoryservice/category/001,访问到category id 001的分类。{id}就好比参数。接着,让我们看看@PathParam注解。@PathParam注解是用来给URI 路径一个模板变量,方法的输入参数。@PathParam("id") 就是URI中的 @Path ("/category/{id}")

 

@GET

       @Path("/category/{id}")

       public Category getCategory(@PathParam("id") String id)

 

异常处理

 

让我们看一种情况,客户端发送一个请求删除或者更新一个分类,但是这个分类并不存在,那么服务端需要返回正确的错误信息给客户端。

 

为了处理异常,JAX-RS提供了WebApplicationException,它继承自RuntimeException类。WebApplicationException可以使用HTTP状态代码或者javax.ws.rs.core.Response对象作为构造器。Response对象除了提供HTTP状态代码外,还可以提供用户容易识别的错误信息。

 

RESTful服务的异常处理可以分为如下几类:

 

实现类抛出带有HTTP错误代码的WebApplicationException异常。一般的,4XX定义了客户端错误,如错误请求;5XX定义了服务端错误,如服务器没有完成请求。

直接发回javax.ws.rs.core.Response对象,Response对象中包含了HTTP错误代码。

 

为了测试异常处理代码,启动CategoryServerStart类。在IE浏览器中输入

http://localhost:9000/categoryservice/category/011

由于IE不会显示自定义的错误信息,我们会看到HTTP 400 BAD Request

如果你在Firefox或者Chrome,就会返回

<error>Category Not Found</error>

 

 

 

添加JSON支持

 

@Produces @Consumes注解中添加application/json,指定CategoryService除了application/xml外,还接收和产生application/jsonCXF运行时会处理HTTP JSON请求到JAVA对象的转换,还有JAVA对象到HTTP JSON响应的映射。

package demo.restful;

//JAX-RS Imports
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;

/*
 * CategoryService class - Add/Removes category for books 
 */

@Path("/categoryservice")
@Produces({"application/json","application/xml"})
public class CategoryService {

	private CategoryDAO categoryDAO = new CategoryDAO();

	public CategoryDAO getCategoryDAO() {
		return categoryDAO;
	}

	public void setCategoryDAO(CategoryDAO categoryDAO) {
		this.categoryDAO = categoryDAO;
	}

	@GET
	@Path("/category/{id}")
	@Produces({"application/json","application/xml"})
	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/json","application/xml"})
	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}")
	@Consumes({"application/json","application/xml"})
	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")
	@Consumes({"application/json","application/xml"})
	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/json","application/xml"})
	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();

		}
	}

}

 

 

 

 

DAO

 

 

package demo.restful;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/*
 * DataAcess object for performing CRUD operations.
 * Dummy implementation.
 */
public class CategoryDAO {

	private static Map<String, Category> categoryMap = new HashMap<String, Category>();
	private static Map<String, Collection<Book>> bookMap = new HashMap<String, Collection<Book>>();

	static {

		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");

		Collection<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);

	}

	public void addBook(Category category) {
		bookMap.put(category.getCategoryId(), category.getBooks());

	}

	public Collection<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);

	}

}

 

 

 

创建调用RESTful服务的客户端

 

JAX-RS并不提供调用RESTful服务客户端。CXF框架提供了两种方式来创建客户端,这两种都可以使用Spring配置。

 

代理API

代理API允许你使用RESTful服务的资源类和接口。代理类是客户端直接调用接口方法,使用户不需要手工创建HTTP请求。将RESTful服务类传递给org.apache.cxf.jaxrs.client.JAXRSClientFactory类。一旦代理类创建好了,你可以直接使用RESTful服务接口类的任何方法。

 

CategoryService store = JAXRSClientFactory.create("http://

localhost:9000", CategoryService.class);

//Makes remote call to Category RESTFul service

store.getBooks("001");

 

HTTP客户端

使用org.apache.cxf.jaxrs.client.WebClient调用RESTful服务。本例中采用HTTP客户端。

 

package demo.restful.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.ws.rs.core.Response;

import org.apache.cxf.jaxrs.client.WebClient;

import demo.restful.Book;
import demo.restful.Category;

public class CategoryServiceRESTClient {

    //Put some static value
    private static final String CATEGORY_URL = "http://localhost:9000/";
    private static final String CATEGORY_ID = "005";
    private static final String TYPE_XML = "application/xml";
    private static final String TYPE_JSON = "application/json";

    public static void main(String[] args) {

        //System.out.println("Format is " + args[0]);

        testAddCategory(TYPE_XML);
        testUpdateCategory(TYPE_XML);
        testGetCategory(TYPE_XML);
        testAddBooksForCategory(TYPE_XML);
        testGetBooksForCategory(TYPE_XML);
        testDeleteCategory(TYPE_XML);

        testAddCategory(TYPE_JSON);
        testUpdateCategory(TYPE_JSON);
        testGetCategory(TYPE_JSON);
        testAddBooksForCategory(TYPE_JSON);
        testGetBooksForCategory(TYPE_JSON);
        testDeleteCategory(TYPE_JSON);

//		if(args[0] !=null && args[0].equalsIgnoreCase(TYPE_XML)){
//			//Content type- XML
//			testAddCategory(TYPE_XML);
//			testUpdateCategory(TYPE_XML);
//			testGetCategory(TYPE_XML);
//			testAddBooksForCategory(TYPE_XML);
//			testGetBooksForCategory(TYPE_XML);
//			testDeleteCategory(TYPE_XML);
//		}
//		
//		if(args[0] !=null && args[0].equalsIgnoreCase(TYPE_JSON)){
//			//ContentType- JSON
//			testAddCategory(TYPE_JSON);
//			testUpdateCategory(TYPE_JSON);
//			testGetCategory(TYPE_JSON);
//			testAddBooksForCategory(TYPE_JSON);
//			testGetBooksForCategory(TYPE_JSON);
//			testDeleteCategory(TYPE_JSON);
//		}


    }

    private static void testAddCategory(final String format) {

        System.out.println("testAddCategory called with format " + format);
        WebClient client = WebClient.create(CATEGORY_URL);
        client.path("/categoryservice/category").accept(
                format).type(format);
        Category cat = new Category();
        cat.setCategoryId(CATEGORY_ID);
        cat.setCategoryName("Fiction");
        Category catResponse = client.post(cat, Category.class);
        System.out.println("Category Id retreived for format " + format + " is " + catResponse.getCategoryId());
        assertEquals(catResponse.getCategoryId(), CATEGORY_ID);


    }

    private static void testUpdateCategory(final String format) {

        System.out.println("testUpdateCategory called with format " + format);
        WebClient client = WebClient.create(CATEGORY_URL);
        client.path("/categoryservice/category").accept(
                format).type(format);
        Category cat = new Category();
        cat.setCategoryId(CATEGORY_ID);
        cat.setCategoryName("Fiction Series");
        Response response = client.put(cat);
        System.out.println("Status retreived for update category for format " + format + " is " + response.getStatus());
        assertEquals("200", String.valueOf(response.getStatus()));


    }

    private static void testGetCategory(final String format) {

        System.out.println("testGetCategory called with format " + format);
        WebClient client = WebClient.create(CATEGORY_URL);
        Category category = client.path("/categoryservice/category/" + CATEGORY_ID).accept(
                format).type(format).get(Category.class);
        System.out.println("Category details retreived from service with format " + format);
        System.out.println("Category Name " + category.getCategoryName());
        System.out.println("Category Id " + category.getCategoryId());
        assertEquals(CATEGORY_ID, category.getCategoryId());


    }

    private static void testAddBooksForCategory(final String format) {

        System.out.println("testAddBooksForCategory called with format " + format);
        WebClient client = WebClient.create(CATEGORY_URL);
        client.path("/categoryservice/category/book").type(format).
                accept(format);
        Category cat = new Category();
        cat.setCategoryId(CATEGORY_ID);
        cat.setCategoryName("Fiction Series");
        Book book1 = new Book();
        book1.setAuthor("Naveen Balani");
        book1.setBookId("NB001");
        book1.setBookISBNnumber("ISBNB001");
        book1.setBookName("Fiction Book1");

        Collection<Book> booksList = new ArrayList<Book>();
        booksList.add(book1);
        cat.setBooks(booksList);
        client.post(cat, Category.class);



    }

    private static void testGetBooksForCategory(final String format) {

        System.out.println("testGetBooksForCategory called with format " + format);
        WebClient clientBook = WebClient.create(CATEGORY_URL);
        Category categoryBooks = clientBook.path(
                "/categoryservice/category/" + CATEGORY_ID + "/books").type(format).accept(format).get(Category.class);
        System.out.println("Book details retreived from service with format " + format);

        assertEquals(String.valueOf(categoryBooks.getBooks().size()), "1");

        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());

        }


    }

    private static void testDeleteCategory(final String format) {

        System.out.println("testDeleteCategory called with format " + format);
        WebClient client = WebClient.create(CATEGORY_URL);
        client.path("/categoryservice/category/" + CATEGORY_ID).type(format).
                accept(format);
        Response response = client.delete();
        System.out.println("Status retreived for delete category for format " + format + " is " + response.getStatus());
        assertEquals("200", String.valueOf(response.getStatus()));


    }

    private static void assertEquals(String expected, String result) {
        if (!expected.equalsIgnoreCase(result)) {
            throw new RuntimeException("Expecte value " + expected + ", Got value" + result);
        }
    }
}

 

 

 

 

 

分享到:
评论
20 楼 yadongliang 2018-01-10  
终于找到HelloWorld++的版本...感谢
19 楼 lijunwyf 2015-06-29  
用soapui 怎么报:missing raw request data
18 楼 402230366 2015-04-17  
请问楼主restful路径中,含有多个参数,并且中间的参数有空值null或者空字符串怎么办?用一个常量去定义一下,变相认为是空我知道,还有其他办法吗?
17 楼 86614009 2015-01-15  
rest服务发出去以后,如果方法返回的是对象,在WADL文件里面,并没有对象的描述。
找不到cxf-extension-jaxrs-binding.xml这个文件,这个文件在哪个包里面。
16 楼 glory_2011 2015-01-14  
我想用tomcat发布,进行测试,怎么全部是404错误呢,希望楼主帮忙啊
15 楼 qzywzq 2014-09-11  
要想支持json,需要做以下配置:
beans.xml文件中:
  <jaxrs:server id="categoryRESTService" address="/">
    <jaxrs:providers>
    <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true" />
        <property name="supportUnwrapped" value="true" />
    </bean>
</jaxrs:providers>
  </jaxrs:server>


pom.xml文件中:
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-rs-extension-providers</artifactId>
  <version>${cxf.version}</version>
</dependency>
<dependency>
  <groupId>org.codehaus.jettison</groupId>
  <artifactId>jettison</artifactId>
  <version>1.3.6</version>
    </dependency>
14 楼 qzywzq 2014-09-10  
beans.xml中,需要在由原 classpath: 改为 classpath*:,如下:

  <import resource="classpath*:META-INF/cxf/cxf.xml" />
  <import resource="classpath*:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
  <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />

13 楼 huanghailei 2014-08-07  
工程到时能跑起来,但是你的demo.restful包给改一下放在com.acz.webservice下面时
抛了如下异常
07, 2014 7:08:23 下午 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
警告: Application {http://webservice.acz.com/}CategoryService has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault

启动CategoryServerStart
restServer.setAddress("http://localhost:9000/");是这样设置的。
12 楼 250367976 2014-07-08  
为什么我的都是找不到URL啊,我是跟ssh2整在一起的
11 楼 a380387084 2014-03-28  
引用
[flash=200,200][/flash]
10 楼 yongjian1092 2013-11-06  
为答谢楼主,特来回复。
9 楼 ITvision 2013-08-21  
好,找了一天,才发现,顶起
8 楼 fengfujie 2013-06-26  
2个service  怎么发布
7 楼 Tristan_S 2013-04-26  
54zzb 写道
Tristan_S 写道
请问博主两个问题
1, 客户端的类即Category, Book 如何生成?
2, 有没有第三方的工具类似于xmlspy的来作为工具,测试restful的?
谢谢~

可以根据返回的xml或json数据来定义类的属性,
如:
<Customer>
  <birthday>2013-04-25T16:30:12.047+08:00</birthday>
  <id>zzb</id>
  <name>zzb</name>
  </Customer>
那你就应该知道,这个类名叫Customer,它的属性有birthday,id,name至于这些属性是什么类型,反正xml和json返回给客户端的都是String类型的,你可以根据实际要求设定Category,Book这两个类的属性类型,因为通过.get(Customer.class)系统会自动帮你转换类型的。

谢谢~
6 楼 54zzb 2013-04-25  
Tristan_S 写道
请问博主两个问题
1, 客户端的类即Category, Book 如何生成?
2, 有没有第三方的工具类似于xmlspy的来作为工具,测试restful的?
谢谢~

可以根据返回的xml或json数据来定义类的属性,
如:
<Customer>
  <birthday>2013-04-25T16:30:12.047+08:00</birthday>
  <id>zzb</id>
  <name>zzb</name>
  </Customer>
那你就应该知道,这个类名叫Customer,它的属性有birthday,id,name至于这些属性是什么类型,反正xml和json返回给客户端的都是String类型的,你可以根据实际要求设定Category,Book这两个类的属性类型,因为通过.get(Customer.class)系统会自动帮你转换类型的。
5 楼 paladin1988 2012-12-06  
解决了,感谢你的demo。。
4 楼 paladin1988 2012-12-06  
可否把jar包发给我下,刚才试了一把,我用自己的jar倒是跑起来了,但是测试你的RESTfulClient的时候有问题。。站内联系。。
3 楼 Tristan_S 2012-12-05  
请问博主两个问题
1, 客户端的类即Category, Book 如何生成?
2, 有没有第三方的工具类似于xmlspy的来作为工具,测试restful的?
谢谢~
2 楼 hb_wxd 2012-09-24  
这才是正儿八经的玩意儿,写的不错。
1 楼 mmhotsky 2012-08-16  
不错,正好能用上,感谢LZ分享!

相关推荐

    cxf 开发restful服务

    本文将详细介绍如何使用CXF和Maven来开发RESTful服务。 首先,我们需要理解REST(Representational State Transfer)的核心概念。REST是一种架构风格,它强调资源的识别和通过统一接口进行操作。在RESTful服务中,...

    用CXF开发RESTful风格WebService

    用CXF开发RESTful风格WebService.doc

    CXF Restful服务简单例子

    【CXF Restful服务简单例子】\n\n在IT行业中,Apache CXF是一个广泛使用的开源框架,它允许开发人员创建和消费Web服务。RESTful(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于...

    CXF restful风格WebService

    使用CXF开发RESTful服务,我们可以利用JAX-RS(Java API for RESTful Web Services)规范,它是Java平台上的RESTful服务开发标准。 **三、CXF与JAX-RS** JAX-RS提供了一组注解,如`@Path`、`@GET`、`@POST`、`@PUT...

    cxf webservice restful实现

    在IT行业中,CXF是一个广泛使用的开源框架,用于构建和开发Web服务。它支持多种Web服务规范,包括SOAP和RESTful。本项目聚焦于利用CXF与Spring框架集成,实现RESTful风格的Web服务。REST(Representational State ...

    cxf restful

    总结,不依赖Spring,单纯使用CXF实现RESTful服务,主要是通过定义接口,实现服务逻辑,然后配置CXF服务器来部署和暴露服务。这种方式对于小型项目或学习RESTful服务的原理非常实用,但大型项目中,Spring等框架提供...

    cxf实现restful资料

    CXF允许开发者选择使用Java API for RESTful Web Services (JAX-RS)标准或者CXF自身的API来开发REST服务。JAX-RS是Java平台上的RESTful服务开发标准,提供了一组注解来简化REST服务的实现。 三、Spring与CXF集成 1....

    Spring CXF Restful 实例

    在IT行业中,Spring CXF是一个广泛使用的开源框架,它整合了Spring框架的功能和Apache CXF的服务堆栈,为开发人员提供了构建和实现Web服务的强大工具。在这个“Spring CXF Restful实例”中,我们将深入探讨如何利用...

    cxf_restful_webservice

    在这个项目中,开发者使用MyEclipse 10作为集成开发环境,它提供了丰富的工具支持,如代码编辑、调试、部署等功能,便于快速构建和测试CXF RESTful Web服务。Tomcat 7则是一个流行的开源Servlet容器,用于运行Java ...

    RestFul(一)WebService之CXF的RestFul风格开发

    本篇文章将探讨在Java领域中,如何使用Apache CXF框架实现RESTful风格的Web服务开发。** **1. RESTful风格的基本概念** RESTful风格的核心理念是将网络上的各种资源抽象为URI(统一资源标识符),并通过HTTP方法...

    SpringBoot+Mybatis+CXF框架,实现Restful api与 WebService api接口的大实验

    本实验的主要目标是使用SpringBoot、Mybatis和CXF框架来实现Restful API和WebService API接口的大实验。下面是实验的详细介绍: 标题:SpringBoot+Mybatis+CXF框架,实现Restful api与 WebService api接口的大实验 ...

    利用CXF发布restful WebService 研究

    【标题】:“利用CXF发布RESTful WebService研究” 在当今的互联网开发中,RESTful Web ...通过以上知识点的学习,读者可以掌握使用Apache CXF构建RESTful Web Service的基础技能,并能将其应用到实际的项目开发中。

    spring + cxf + restful

    在IT行业中,Spring、CXF和RESTful是三个非常重要的技术组件,它们分别代表了Java应用框架、服务开发和Web服务API设计模式。本篇文章将深入解析这些技术,并结合"spring + cxf + restful"的实践项目"taiping-account...

    CXF3.0+Spring3.2 RESTFul服务(下)

    CXF,一个强大的开源服务框架,支持SOAP和RESTful服务,而Spring作为Java应用开发的基石,提供了强大的依赖注入和管理能力。本文将深入探讨如何结合CXF3.0.2和Spring3.2.14来构建RESTful服务,并以JSON作为数据交换...

    cxf发布RestFul接口。 maven

    在IT行业中,CXF是一个广泛使用的开源框架,用于构建和开发Web服务,包括SOAP和RESTful接口。本篇文章将深入探讨如何使用CXF、Spring、Maven等技术栈来发布一个支持HTTP请求和SOAP调用的RestFul接口。 首先,我们...

    cxf集成Spring的restful WebService接口

    总之,通过将CXF与Spring框架集成,我们可以利用Spring的强大功能来管理和配置服务,同时利用CXF的灵活性来快速开发RESTful接口。这种组合为Java开发者提供了一个高效且可扩展的解决方案,用于构建现代化的、基于...

    CXF RESTful spring maven CRUD

    **标题解析:** "CXF RESTful spring maven CRUD" 这个标题表明这是一个使用CXF框架、Spring和Maven构建的RESTful Web服务的示例项目,它实现了CRUD(创建、读取、更新、删除)操作。CXF是一个开源的服务框架,它...

Global site tag (gtag.js) - Google Analytics