利用webservice交互有SOAP和REST两种方式,SOAP是协议,REST不是协议,它是一个过程,利用HTTP协议对应的GET,POST,PUT,DELETE四种方法对应查、增、改、删中方式。REST比较松散,它用来对资源数据的传输,效率高,但是还是要根据实际情况选择SOAP还是REST方式。
对于REST,官网给出了三种方式,第一种java方式,第二种jaxws方式,第三种(已经淘汰),本例我是第一种方式,第二种方式官网的例子本人也测试过,很简洁,但是不是很好懂,资料上一般都选第一种方式基于jaxrs的。(官网太不详细:http://cxf.apache.org/docs/restful-services.html)
下面给出一个我实现了的例子来说明。
首先来看看我的项目结构:
我们把基础的类
Book.java和Category.java先展示如下:
package demo.restful;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Book")
public class Book {
private String bookId;
private String bookISBNnumber;
private String bookName;
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;
}
}
数据操作的Dao类
package demo.restful;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Repository;
@Repository
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("Tian jun");
book1.setBookName("Spring MVC");
book1.setBookId("001");
book1.setBookISBNnumber("isbn001");
Book book2 = new Book();
book2.setAuthor("t jun123");
book2.setBookName("CXF WEB SERvice");
book2.setBookId("002");
book2.setBookISBNnumber("isbn002");
Collection<Book> bookList = new ArrayList<Book>();
bookList.add(book1);
bookList.add(book2);
bookMap.put(category1.getCategoryId(), bookList);
}
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;
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);
bookMap.remove(id);
}
public void updateCategory(Category category){
categoryMap.put(category.getCategoryId(), category);
}
}
业务逻辑类,也是进行消息处理的映射类
package demo.restful;
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.core.Response;
import javax.ws.rs.core.Response.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Path("/categoryservice")
@Produces("application/xml")
public class CategoryService {
@Autowired
private CategoryDAO categoryDAO;
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 = getCategoryDao().getCategory(id);
return cat;
}
@POST
@Path("/category")
@Consumes("application/xml")
public void addCategory(Category category){
System.out.println("addcategory called");
Category cat = getCategoryDao().getCategory(category.getCategoryId());
if(cat != null){
// return Response.status(Status.BAD_REQUEST).build();
getCategoryDao().addCategory(category);
}
// else{
getCategoryDao().addCategory(category);
// return Response.ok(category).build();
// }
}
@DELETE
@Path("/catagory/{id}")
public void deleteCategory(@PathParam("id") String id){
System.out.println("deleteCategory with category id:"+id);
getCategoryDao().deleteCategory(id);
}
@PUT
@Path("/category")
public void updateCategory(Category category){
System.out.println("updateCategory with id:"+category.getCategoryId());
getCategoryDao().updateCategory(category);
}
@POST
@Path("/category/book")
@Consumes("application/xml")
public void addBooks(Category category){
System.out.println("addBook with category id:"+category.getCategoryId());
Category cat = getCategoryDao().getCategory(category.getCategoryId());
getCategoryDao().addBook(category);
}
@GET
@Path("/category/{id}/books")
@Consumes("application/xml")
public Category getBooks(@PathParam("id") String id){
System.out.println("getBooks called with id:"+id);
Category cat = getCategoryDao().getCategory(id);
cat.setBooks(getCategoryDao().getBooks(id));
return cat;
}
}
最后启动服务端:
</pre><pre name="code" class="java">package demo.restful;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CategoryServiceStart {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("==============");
ClassPathXmlApplicationContext appcontext = new ClassPathXmlApplicationContext(new String[]{"restapp.xml"});
CategoryService categoryservice = (CategoryService) appcontext.getBean("categoryService");
JAXRSServerFactoryBean restServer = new JAXRSServerFactoryBean();
restServer.setResourceClasses(Category.class);
restServer.setServiceBean(categoryservice);
restServer.setAddress("http://localhost:9000/");
restServer.create();
// BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// try{
// br.readLine();
// }catch (IOException e){
// e.printStackTrace();
// }
// System.out.println("*************$$$$$$$$**********************");
// List<Class<?>> resourceClassList = new ArrayList<Class<?>>();
// resourceClassList.add(CategoryService.class);
//
// List<ResourceProvider> resourceProviderList= new ArrayList<ResourceProvider>();
// resourceProviderList.add(new SingletonResourceProvider(new CategoryService()));
//
// List<Object> providerList = new ArrayList<Object>();
// providerList.add(new jackson);
//
// JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
// factory.setAddress("http://localhost:8080/WS/rest");
// factory.setResourceClasses(resourceClassList);
// factory.setResourceProviders(resourceProviderList);
// factory.setProvider(providerList);
// factory.create();
System.out.println("rest ws is publish....");
}
}
可以直接在浏览器中输入如下:
http://localhost:9000/categoryservice/category/001
看到如下:
浏览器中输入:
http://localhost:9000/categoryservice/category/001/books
看到如下:
当然我们也可以编写客户端来实现:
代码如下:
package demo.restful.client;
import java.util.Iterator;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.jaxrs.client.WebClient;
import demo.restful.Book;
import demo.restful.Category;
public class CategoryServiceClient {
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 RESTful service...");
System.out.println("category Name "+category.getCategoryName());
System.out.println("category id "+category.getCategoryId());
System.out.println("Book details for categroy "+category.getCategoryId()+" from REST service");
String bookString ="categoryservice/category/"+category.getCategoryId()+"/books";
WebClient clientBook = WebClient.create("http://localhost:9000/");
try{
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());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
效果如下:如图大家看到的是编写Application发布实现的,由于我们是web,所以想利用Spring发布到服务器上。
资料和网上的都是利用jaxrs:server属性来实现的,我用的CXF是最新的3.1.1的版本,写上jaxrs:server属性,不提示错,但是编译的时候会爆没这个属性,官网信息太零散了,我还没找到最新版本的spring发布方式,有知道的可以告诉一声或交流下,不剩感激……