SOA专题

使用Apache CXF开发Web服务

  SOAP是一个基于XML的信息交换用的应用协议,如HTTP,SMTP等网络协议,作为载体。SOAP消息包括SOAP信封。信封可分为标题和正文。标题包含上下文相关的定义如安全,内容body包含的是实际应用数据。一个典型的SOAP消息看起来像

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
  </soap:Header>
  <soap:Body>
    <m:GetStockPrice xmlns:m="http://www.example.org/stock">
      <m:StockName>IBM</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>

WSDL or Web Services 描述语言

WSDL是一个用于描述Web服务的基于XML语言的标准。WSDL完全描述了Web服务公开的公共接口,需要的参数,返回输出结构,Web服务的位置。一个WSDL定义Web服务作为一个集合,这个集合保护能够交换信息的通信端点endpoint。这些通信端点endponit称为端口port。port由两部分组成的

1.包含了通过Web服务公开的公共接口。该接口包含所有的方法所需要的参数来调用和响应返回结构

2.绑定公共接口到网络协议像HTTP。绑定信息结合包括服务的公共接口 消息格式 位置信息

SOAP联系风格

有两种:

  1. Document
  2. RPC
通讯风格是在SOAP web service使用,在WSDL.中定义。

在document中,SOAP消息体中的应用数据作为XML文件的发送,可以被WSDL的XML Schema校验,而XML应该包含web服务开发者的期望结构,以便XML能够被序列化和反序列化传送。

RPC风格顾名思义消费者调用服务的方法好像调用本地方法,为了实现这个RPC,消息是由公共接口的方法组成,使用者可以调用列表。这些方法以名称列表作为XML元素。还有该方法所需参数的方法,这些方法的子方法。序列化和反序列化是由Web框架完成,它含有自己的处理库包。RPC风格导致在应用程序代码和Web服务框架之间的紧密耦合。

服务端代码下载:http://subversion.assembla.com/svn/weblog4j/Weblog4jDemo/trunk

客户端下载:http://subversion.assembla.com/svn/weblog4j/DemoClient/trunk

用Struts2作为依托加入CXF:

我们还是使用使用Apache CXF开发RESTful服务中的书架服务:

创建一个服务端点接口SEI:Service Endpoint Interface

package com.aranin.weblog4j.services;

import com.aranin.weblog4j.vo.BookVO;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface BookShelfService {

    @WebMethod
    public  String insertBook(BookVO bookVO);
    @WebMethod
    public  BookVO getBook(String title);
}

  • @WebService – 这是JAXWS库的元注解.将一个普通的POJO转为普通服务,BookShelfService 不是一个普通接口,而是一个web服务结构SEI。
  • @WebMethod – 提供WSDL中公共方法的名称,可选。

实现服务接口:

package com.aranin.weblog4j.services;

import com.aranin.weblog4j.hashdb.HashDB;
import com.aranin.weblog4j.vo.BookVO;

import javax.jws.WebService;

@WebService(endpointInterface = "com.aranin.weblog4j.services.BookShelfService",
              serviceName="bookShelfService")
public class BookShelfServiceImpl implements BookShelfService {
    public String insertBook(BookVO bookVO) {
        HashDB.insertBook(bookVO);
        return "Book with name : " + bookVO.getBookName() + " is now available on the shelf";  //To change body of implemented methods use File | Settings | File Templates.
    }

    public BookVO getBook(String title) {

        return HashDB.getBook(title);  //To change body of implemented methods use File | Settings | File Templates.
    }
}

Spring中的配置:

<?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"
       xsi:schemaLocation="

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-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

<jaxws:endpoint
       id="bookShelfService"
       implementor="com.aranin.weblog4j.services.BookShelfServiceImpl"
       address="/bookshelfservice" />

</beans>

服务在http://localhost:8080/weblog4jdemo/bookshelfservice?wsdl

创建调用客户端:

package com.aranin.weblog4j.client;

import com.aranin.weblog4j.services.BookShelfService;
import com.aranin.weblog4j.vo.BookVO;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class DemoClient {
    public static void main(String[] args){
        String serviceUrl = "http://localhost:8080/weblog4jdemo/bookshelfservice";
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
              factory.setServiceClass(BookShelfService.class);
              factory.setAddress(serviceUrl);
              BookShelfService bookService = (BookShelfService) factory.create();

        //insert book
        BookVO bookVO = new BookVO();
        bookVO.setAuthor("Issac Asimov");
        bookVO.setBookName("Foundation and Earth");

        String result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        bookVO = new BookVO();
        bookVO.setAuthor("Issac Asimov");
        bookVO.setBookName("Foundation and Empire");

        result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        bookVO = new BookVO();
        bookVO.setAuthor("Arthur C Clarke");
        bookVO.setBookName("Rama Revealed");

        result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        //retrieve book

        bookVO = bookService.getBook("Foundation and Earth");

        System.out.println("book name : " + bookVO.getBookName());
        System.out.println("book author : " + bookVO.getAuthor());

    }
}

输出结果:

INFO: Creating Service {http://services.weblog4j.aranin.com/}BookShelfServiceService from class com.aranin.weblog4j.services.BookShelfService
result : Book with name : Foundation and Earth is now available on the shelf
result : Book with name : Foundation and Empire is now available on the shelf
result : Book with name : Rama Revealed is now available on the shelf
book name : Foundation and Earth
book author : Issac Asimov

Process finished with exit code 0

 

 

使用Apache CXF开发RESTful服务

使用Spring Webservices建立SOAP服务代理