webservice cxf学习

第一步:新建一个webservice接口

@WebService  
public interface IHelloWorld {   
webservice cxf学习    //@WebParam给参数命名,提高可代码可读性。此项可选   
webservice cxf学习blic String sayHi(@WebParam(name="text") String text);   
webservice cxf学习}  
webservice cxf学习


通过注解@WebService申明为webservice接口
   第二步,实现WebService接口

 @WebService  
  public class HelloWorldImpl implements IHelloWorld {   
webservice cxf学习  
webservice cxf学习public String sayHi(String name) {   
webservice cxf学习    System.out.println("sayHello is called by " + name);   
webservice cxf学习    return "Hello " + name;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习   }  
webservice cxf学习


第三步,创建服务端

 public class Server {   
  
webservice cxf学习private Server(){   
webservice cxf学习    IHelloWorld helloWorld = new HelloWorldImpl();   
webservice cxf学习    //创建WebService服务工厂   
webservice cxf学习    JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();   
webservice cxf学习    //注册WebService接口   
webservice cxf学习    factory.setServiceClass(IHelloWorld.class);   
webservice cxf学习    //发布接口   
webservice cxf学习    factory.setAddress("http://localhost:9000/HelloWorld");   
webservice cxf学习    factory.setServiceBean(helloWorld);   
webservice cxf学习    //创建WebService   
webservice cxf学习    factory.create();   
webservice cxf学习};   
webservice cxf学习  
webservice cxf学习public static void main(String[] args) throws InterruptedException{   
webservice cxf学习       //启动服务端   
webservice cxf学习              new Server();   
webservice cxf学习    System.out.println("Server readywebservice cxf学习");   
webservice cxf学习    //休眠一分钟,便于测试   
webservice cxf学习               Thread.sleep(1000*60);   
webservice cxf学习    System.out.println("Server exitwebservice cxf学习");   
webservice cxf学习    System.exit(0);   
webservice cxf学习}   
webservice cxf学习   }  
webservice cxf学习


第四步,创建客户端

public class Client {   
  
webservice cxf学习private Client(){};   
webservice cxf学习  
webservice cxf学习public static void main(String[] args){   
webservice cxf学习    //创建WebService客户端代理工厂   
webservice cxf学习    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();   
webservice cxf学习    //注册WebService接口   
webservice cxf学习    factory.setServiceClass(HelloWorld.class);   
webservice cxf学习    //设置WebService地址   
webservice cxf学习    factory.setAddress("http://localhost:9000/HelloWorld");        
webservice cxf学习    IHelloWorld iHelloWorld = (IHelloWorld)factory.create();   
webservice cxf学习    System.out.println("invoke webservicewebservice cxf学习");   
webservice cxf学习    System.out.println("message context is:"+iHelloWorld.sayHi("     
webservice cxf学习                 Josen"));   
webservice cxf学习    System.exit(0);   
webservice cxf学习}   
webservice cxf学习   }   
webservice cxf学习


首先,运行服务端程序
    其次,打开浏览器,在地址栏中输入http://localhost:9000/HelloWorld?wsdl(因为cxf自带了一个jetty服务器),查看接口是否发布成功,如里浏览器页面显示下面内容,证明接口发布成功

本文所引用的资源主要包括两类,一类是Web服务的技术资源网站,包含了大量Web服务的技术信息,另一类是Web服务“stack"系列技术规范,他们是一个整体的技术体系,包括UDDI、SOAP、WSDL、XML等。本文的最后给出了这些资源的链接,有兴趣的读者可以通过这些资源链接找到所需的内容。
webservice cxf学习

其中,绿色部分是先前已经定义好的并且广泛使用的传输层和网络层的标准:IP、HTTP、SMTP等。而蓝色部分是目前开发的Web服务的相关标准协议,包括服务调用协议SOAP、服务描述协议WSDL和服务发现/集成协议UDDI,以及服务工作流描述语言WSFL。而橙色部分描述的是更高层的待开发的关于路由、可靠性以及事务等方面的协议。黄色部分是各个协议层的公用机制,这些机制一般由外部的正交机制来完成。

其中,一个可以使用的Web服务应当按照需要选用若干层次的功能,而无需所有的特性。但是无论如何为了实现一个一般意义上的Web服务,具备Web服务的基础特性:跨平台调用和接口可机器识别,那么必需使用WSDL和SOAP。SOAP是用来最终完成Web服务调用的,而WSDL则是用于描述如何使用 SOAP来调用Web服务的。

    WSDL 是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问(类似远程过程调用)。WSDL首先对访问的操作和访问时使用的请求/响应消息进行抽象描述,然后将其绑定到具体的传输协议和消息格式上以最终定义具体部署的服务访问点。相关的具体部署的服务访问点通过组合就成为抽象的Web服务。

    在具体使用中,我们可以对 WSDL 进行扩展(类似SOAP的可扩展性),这样无论通信时使用何种消息格式或网络协议,都可以对服务访问点及其使用的消息格式进行描述。在WSDL的框架中,可以使用任意的消息格式和网络协议,如同SOAP中可以使用任意的网络协议一样。在WSDL规范中,定义了如何使用SOAP消息格式、HTTP GET/POST消息格式以及MIME格式来完成Web服务交互的规范。

WSDL 文档将Web服务定义为服务访问点或端口的集合。在 WSDL 中,由于服务访问点和消息的抽象定义已从具体的服务部署或数据格式绑定中分离出来,因此可以对抽象定义进行再次使用:消息,指对交换数据的抽象描述;而端口类型,指操作的抽象集合。用于特定端口类型的具体协议和数据格式规范构成了可以再次使用的绑定。将Web访问地址与可再次使用的绑定相关联,可以定义一个端口,而端口的集合则定义为服务。因此,WSDL 文档在Web服务的定义中使用下列元素:

  * Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。 
    * Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。 
webservice cxf学习    * Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。 
webservice cxf学习    * PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。 
webservice cxf学习    * Binding - 特定端口类型的具体协议和数据格式规范的绑定。 
webservice cxf学习    * Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。 
webservice cxf学习    * Service - 相关服务访问点的集合。 


大家可以参考下图,来理解一下WSDL文档的结构组织:
webservice cxf学习

其中,Types是一个数据类型定义的容器,包含了所有在消息定义中需要的XML元素的类型定义,我将在今后的文章中结合XML Schema来详细说明如何进行类型定义。

    Message具体定义了在通信中使用的消息的数据结构,Message元素包含了一组Part元素,每个Part元素都是最终消息的一个组成部分,每个 Part都会引用一个DataType来表示它的结构。Part元素不支持嵌套(可以使用DataType来完成这方面的需要),都是并列出现。

    PortType具体定义了一种服务访问入口的类型,何谓访问入口的类型呢?就是传入/传出消息的模式及其格式。一个PortType可以包含若干个 Operation,而一个Operation则是指访问入口支持的一种类型的调用。在WSDL里面支持四种访问入口调用的模式:

   1. 单请求;
   2. 单响应;
   3. 请求/响应;
   4. 响应/请求。
在这里请求指的是从客户端到Web服务端,而响应指的是从Web服务端到客户端。PortType的定义中会引用消息定义部分的一个到两个消息,作为请求或响应消息的格式。比如,一个股票查询的访问入口可能就会支持两种请求消息,一种请求消息中指明股票代码,而另一种请求消息中则会指明股票的名称,响应消息可能都是股票的价格等等。

    以上三种结构描述了调用Web服务的抽象定义,这三部分与具体Web服务部署细节无关,是可复用的描述(每个层次都可以复用)。如果与一般的对象语言做比较的话,这部分可以堪称是IDL描述的对象,描述了对象的接口标准,但是到底对象是用哪种语言实现,遵从哪种平台的细节规范,被部署在哪台机器上则是后面的元素所描述的。

    Service描述的是一个具体的被部署的Web服务所提供的所有访问入口的部署细节,一个Service往往会包含多个服务访问入口,而每个访问入口都会使用一个Port元素来描述。

    Port描述的是一个服务访问入口的部署细节,包括通过哪个Web地址(URL)来访问,应当使用怎样的消息调用模式来访问等。其中消息调用模式则是使用Binding结构来表示。

    Binding结构定义了某个PortType与某一种具体的网络传输协议或消息传输协议相绑定,从这一层次开始,描述的内容就与具体服务的部署相关了。比如可以将PortType与SOAP/HTTP绑定,也可以将PortType与MIME/SMTP相绑定等。

    在介绍了WSDL的主要元素之后,大家会发现,WSDL的设计理念完全继承了以XML为基础的当代Web技术标准的一贯设计理念:开放。WSDL允许通过扩展使用其他的类型定义语言(不光是XML Schema),允许使用多种网络传输协议和消息格式(不光是在规范中定义的这些:SOAP/HTTP,HTTP-GET/POST以及MIME等)。同时WSDL也应用了当代软件工程中的复用理念,分离了抽象定义层和具体部署层,使得抽象定义层的复用性大大增加。比如我们可以先使用抽象定义层为一类 Web服务进行抽象定义(比如UDDI Registry,抽象定义肯定是完全一致的遵循了UDDI规范),而不同的运营公司可以采用不同的具体部署层的描述结合抽象定义完成其自身的Web服务的描述。
WSDL文档示例
    下例是一个提供股票报价的简单Web服务的 WSDL 定义。该服务支持名为 GetLastTradePrice 的单一操作,这个操作是通过在 HTTP 上运行 SOAP 1.1 协议来实现的。该请求接受一个类型为字符串的 tickerSymbol,并返回类型为浮点数的价格。
 

<?xml version="1.0"?>   
<definitions name="StockQuote"    
webservice cxf学习             targetNamespace="http://example.com/stockquote.wsdl"  
webservice cxf学习             xmlns:tns="http://example.com/stockquote.wsdl"  
webservice cxf学习             xmlns:xsd1="http://example.com/stockquote.xsd"  
webservice cxf学习             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  
webservice cxf学习             xmlns="http://schemas.xmlsoap.org/wsdl/">   
webservice cxf学习                
webservice cxf学习    
webservice cxf学习  <types>   
webservice cxf学习    <schema targetNamespace="http://example.com/stockquote.xsd"  
webservice cxf学习            xmlns="http://www.w3.org/1999/XMLSchema">   
webservice cxf学习      <element name="TradePriceRequest">   
webservice cxf学习        <complexType>   
webservice cxf学习          <all>   
webservice cxf学习            <element name="tickerSymbol" type="string"/>   
webservice cxf学习          </all>   
webservice cxf学习        </complexType>   
webservice cxf学习      </element>   
webservice cxf学习      <element name="TradePriceResult">   
webservice cxf学习        <complexType>   
webservice cxf学习          <all>   
webservice cxf学习            <element name="price" type="float"/>   
webservice cxf学习          </all>   
webservice cxf学习        </complexType>   
webservice cxf学习      </element>   
webservice cxf学习    </schema>   
webservice cxf学习  </types>  
webservice cxf学习


上面这部分是数据类型的定义,其中为定义了两个元素的结构:

    * TradePriceRequest(交易价格请求): 将该元素定义为包含一个字符串元素(tickerSymbol)的复合类型元素。
    * TradePriceResult(交易价格): 将该元素定义为一个包含一个浮点数元素(price)的复合类型元素。

message name="GetLastTradePriceInput">   
    <part name="body" element="xsd1:TradePriceRequest"/>   
webservice cxf学习  </message>   
webservice cxf学习    
webservice cxf学习  <message name="GetLastTradePriceOutput">   
webservice cxf学习    <part name="body" element="xsd1:TradePriceResult"/>   
webservice cxf学习  </message>  
webservice cxf学习


这部分是消息格式的抽象定义,其中定义了两个消息格式:

    * GetlastTradePriceInput(获取最后交易价格的请求消息格式): 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceRequest。(前面已经定义过了)
    * GetLastTradePriceOutput(获取最后交易价格的响应消息格式) : 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceResult。(前面已经定义过了)

<portType name="StockQuotePortType">   
   <operation name="GetLastTradePrice">   
webservice cxf学习     <input message="tns:GetLastTradePriceInput"/>   
webservice cxf学习     <output message="tns:GetLastTradePriceOutput"/>   
webservice cxf学习   </operation>   
webservice cxf学习 </portType>  
webservice cxf学习


这部分定义了服务访问点的调用模式的类型,表明StockQuoteService的某个入口类型是请求/响应模式,请求消息是GetlastTradePriceInput,而响应消息是GetLastTradePriceOutput。

binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">   
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>   
webservice cxf学习      <operation name="GetLastTradePrice">   
webservice cxf学习        <soap:operation soapAction="http://example.com/GetLastTradePrice"/>   
webservice cxf学习          <input>   
webservice cxf学习            <soap:body use="literal" namespace="http://example.com/stockquote.xsd"  
webservice cxf学习                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>   
webservice cxf学习          </input>   
webservice cxf学习          <output>   
webservice cxf学习            <soap:body use="literal" namespace="http://example.com/stockquote.xsd"  
webservice cxf学习                       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>   
webservice cxf学习          </output>   
webservice cxf学习        </soap:operation>   
webservice cxf学习      </operation>   
webservice cxf学习    </soap:binding>   
webservice cxf学习  </binding>  
webservice cxf学习

 这部分将服务访问点的抽象定义与SOAP HTTP绑定,描述如何通过SOAP/HTTP来访问按照前面描述的访问入口点类型部署的访问入口。其中规定了在具体SOAP调用时,应当使用的 soapAction是"http://example.com/GetLastTradePrice",而请求/响应消息的编码风格都应当采用SOAP 规范默认定义的编码风格" http://schemas.xmlsoap.org/soap/encoding/"。

<service name="StockQuoteService">   
    <documentation>股票查询服务</documentation>    
webservice cxf学习    <port name="StockQuotePort" binding="tns:StockQuoteBinding">   
webservice cxf学习    <soap:address location="http://example.com/stockquote"/>   
webservice cxf学习    </port>   
webservice cxf学习  </service>   
webservice cxf学习    
webservice cxf学习</definitions>  
webservice cxf学习


这部分是具体的Web服务的定义,在这个名为StockQuoteService的Web服务中,提供了一个服务访问入口,访问地址是"http://example.com/stockquote",使用的消息模式是由前面的binding所定义的。

    按照这个WSDL文档的描述,在具体Web服务的使用中,具体发生的SOAP交互可能如下面所示:
SOAP消息请求:
 

POST /StockQuote HTTP/1.1  
Host: example.com   
webservice cxf学习Content-Type: text/xml; charset="utf-8"  
webservice cxf学习Content-Length: nnnn   
webservice cxf学习SOAPAction: "http://example.com/GetLastTradePrice"  
webservice cxf学习  
webservice cxf学习<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  
webservice cxf学习                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">   
webservice cxf学习  <SOAP-ENV:Body>   
webservice cxf学习    <m:TradePriceRequest xmlns:m="http://example.com/stockquote.xsd">   
webservice cxf学习      <tickerSymbol>MSFT</tickerSymbol >   
webservice cxf学习    </m:TradePriceRequest>   
webservice cxf学习  </SOAP-ENV:Body>   
webservice cxf学习</SOAP-ENV:Envelope>  
webservice cxf学习

SOAP消息响应:

HTTP/1.1 200 OK   
Content-Type: text/xml; charset="utf-8"  
webservice cxf学习Content-Length: nnnn   
webservice cxf学习  
webservice cxf学习<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  
webservice cxf学习                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>   
webservice cxf学习  <SOAP-ENV:Body>   
webservice cxf学习    <m:TradePriceResult xmlns:m=" http://example.com/stockquote.xsd ">   
webservice cxf学习      <price>74.5</price>   
webservice cxf学习    </m:TradePriceResult >   
webservice cxf学习  </SOAP-ENV:Body>   
webservice cxf学习</SOAP-ENV:Envelope>  
webservice cxf学习



    JAX-WS规范是一组XML web services的JAVA API。JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。
  在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP。在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对于SOAP消息。
  在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI (service endpoint interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。
  在客户端,用户可以通过JAX-WS的API创建一个代理(用本地对象来替代远程的服务)来实现对于远程服务器端的调用。
  通过web service所提供的互操作环境,我们可以用JAX-WS轻松实现JAVA平台与其他编程环境(.net等)的互操作。 

  JAX-WS工作原理如下图所示
webservice cxf学习

前面几节都是讲一些理论知识,现在又用一个例子来说明一下,这一节我们就CXF框架对象传递进行讲解。

  @XmlRootElement(name="Customer")   
   @XmlAccessorType(XmlAccessType.FIELD)   
webservice cxf学习   @XmlType(propOrder = {"name","age"})   
webservice cxf学习   public class Customer {   
webservice cxf学习  
webservice cxf学习private int age;   
webservice cxf学习private String name;   
webservice cxf学习  
webservice cxf学习public int getAge() {   
webservice cxf学习    return age;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setAge(int age) {   
webservice cxf学习    this.age = age;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public String getName() {   
webservice cxf学习    return name;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setName(String name) {   
webservice cxf学习    this.name = name;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习   }  
webservice cxf学习

    @XmlRootElement-指定XML根元素名称(可选) 
   @XmlAccessorType-控制属性或方法序列化 

FIELD-对每个非静态,非瞬变属性JAXB工具自动绑定成XML,除非注明XmlTransient 
    NONE-不做任何处理 
webservice cxf学习    PROPERTY-对具有set/get方法的属性进行绑定,除非注明XmlTransient 
webservice cxf学习    PUBLIC_MEMBER -对有set/get方法的属性或具有共公访问权限的属性进行绑定,除非注 
webservice cxf学习    明XmlTransient 
webservice cxf学习    @XmlType-映射一个类或一个枚举类型成一个XML Schema类型 
webservice cxf学习



    @XmlType-映射一个类或一个枚举类型成一个XML Schema类型
第二步:创建WebService接口

@WebService  
  public interface HelloService {   
webservice cxf学习  
webservice cxf学习public void save(Customer c1,Customer c2);   
webservice cxf学习  
webservice cxf学习public void test(String args);   
webservice cxf学习  
webservice cxf学习public Customer get(int id);   
webservice cxf学习 }   
webservice cxf学习

@WebService  
  public class HelloServiceImpl implements HelloService {   
webservice cxf学习  
webservice cxf学习public void save(Customer c1, Customer c2) {   
webservice cxf学习  
webservice cxf学习    System.out.println(c1.getAge()+"---"+c2.getAge());   
webservice cxf学习    System.out.println(c1.getName()+"---"+c2.getName());   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void test(String args) {   
webservice cxf学习    System.out.println(args);   
webservice cxf学习       
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public Customer get(int id) {   
webservice cxf学习    Customer cus = new Customer();   
webservice cxf学习    cus.setAge(100);   
webservice cxf学习    cus.setName("Josen");   
webservice cxf学习    return cus;   
webservice cxf学习}   
webservice cxf学习    
webservice cxf学习}   


第四步:创建服务端

public class SoapServer {   
  
webservice cxf学习public static void main(String[] args){   
webservice cxf学习//两种方法,任选一种发布WebService接口   
webservice cxf学习              //Endpoint.publish("http://localhost:8080/helloService", new    
webservice cxf学习               HelloServiceImpl());   
webservice cxf学习JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();   
webservice cxf学习factory.setAddress("http://localhost:8080/helloService");   
webservice cxf学习factory.setServiceClass(HelloServiceImpl.class);   
webservice cxf学习              factory.getInInterceptors().add(new LoggingInInterceptor());         
webservice cxf学习factory.getOutInterceptors().add(new LoggingOutInterceptor());   
webservice cxf学习factory.create();   
webservice cxf学习  
webservice cxf学习  }   

第五步:创建客户端

 

public class SoapClient {   
  
webservice cxf学习public static void main(String[] args){   
webservice cxf学习    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();   
webservice cxf学习    factory.setAddress("http://localhost:8080/helloService");   
webservice cxf学习    factory.setServiceClass(HelloService.class);   
webservice cxf学习               factory.setServiceClass(HelloServiceImpl.class);   
webservice cxf学习               factory.getInInterceptors().add(new LoggingInInterceptor());   
webservice cxf学习    HelloService service = (HelloService)factory.create();   
webservice cxf学习       
webservice cxf学习    Customer c1 = new Customer();   
webservice cxf学习    c1.setAge(1);   
webservice cxf学习    c1.setName("aaa");   
webservice cxf学习       
webservice cxf学习    Customer c2 = new Customer();   
webservice cxf学习    c2.setAge(2);   
webservice cxf学习    c2.setName("bbb");   
webservice cxf学习       
webservice cxf学习    service.save(c1, c2);   
webservice cxf学习    service.test("aaaaaaaaaaaaa");   
webservice cxf学习}   
webservice cxf学习 }   

最后,测试程序
  运行服务端程序,在浏览器地址栏输入http://localhost:8080/helloService?wsdl查看接口是否发布成功。成功则运行一下客户端程序,看看对象传输是否成功。


现在我们来分析一下控制打印的日志信息。

信息: Inbound Message 
---------------------------- 
webservice cxf学习ID: 1 
webservice cxf学习Address: /HelloWorld 
webservice cxf学习Encoding: UTF-8 
webservice cxf学习Content-Type: text/xml; charset=UTF-8 
webservice cxf学习Headers: {content-type=[text/xml; charset=UTF-8], connection=[keep-alive], Host=[localhost:9000], Content-Length=[184], SOAPAction=[""], User-Agent=[Apache CXF 2.2.2], Content-Type=[text/xml; charset=UTF-8], Accept=[*/*], Pragma=[no-cache], Cache-Control=[no-cache]} 
webservice cxf学习Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:say xmlns:ns1="http://client.itdcl.com/"><text> Josen</text></ns1:say></soap:Body></soap:Envelope> 
webservice cxf学习-------------------------------------- 
webservice cxf学习2010-1-9 20:41:56 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose 
webservice cxf学习信息: Outbound Message 
webservice cxf学习--------------------------- 
webservice cxf学习ID: 1 
webservice cxf学习Encoding: UTF-8 
webservice cxf学习Content-Type: text/xml 
webservice cxf学习Headers: {} 
webservice cxf学习Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><text xmlns="http://client.itdcl.com/">hi Josen</text></soap:Header><soap:Body><ns1:sayResponse xmlns:ns1="http://client.itdcl.com/"></ns1:sayResponse></soap:Body></soap:Envelope> 
webservice cxf学习-------------------------------------- 
webservice cxf学习2010-01-09 20:41:56.578::INFO:  seeing JVM BUG(s) - cancelling interestOps==0 
webservice cxf学习


 当客户端向服器发送请求时,服务端LoggingInInterceptor拉截客户端发送过来的SOAP消息,如下:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Body> 
webservice cxf学习<ns1:sayHi xmlns:ns1="http://client.itdcl.com/"> 
webservice cxf学习<text>Josen</text> 
webservice cxf学习</ns1:sayHi> 
webservice cxf学习</soap:Body> 
webservice cxf学习</soap:Envelope> 
webservice cxf学习
webservice cxf学习

客户端将请求信息封闭在<soap:Body></soap:Body>中,当然也可以将其放到<soap:Header></soap:Header>,只要在@WebParam中的header设置成true,默认为false;
     服务器接到请求之后,响应客户端。同样以SOAP形式将信息封装好发回客户端,SOAP信息如下:
 

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Header> 
webservice cxf学习<text xmlns="http://client.itdcl.com/">hi Josen</text> 
webservice cxf学习</soap:Header> 
webservice cxf学习<soap:Body> 
webservice cxf学习<ns1:sayResponse xmlns:ns1="http://client.itdcl.com/"></ns1:sayResponse> 
webservice cxf学习</soap:Body> 
webservice cxf学习</soap:Envelope> 
webservice cxf学习



前面几节我们讲解对象传递,但是通常情况下我们不直接传对象,因为直接传递对象安全性差,而且暴露了实体对象。所以我们选择传递XML文件,当然也可以传递JSON对象。这节我只针对传递XML,那么JAVA绑定成XML,服务端将XML解析成Java对象有什么工具可用吗,其实这样的工具多的是。这里我选择一个比较简单的JAXB工具来讲解一下。
    JAXB(Java Architecture for XML Binding)提供了一个快速而方便的方式绑定XML Schemas和java,使java程序员能够很方便的在java应用程序中处理XML数据。JAXB提供了将XML文档解组为java内容树的方法,以及将java内容树重新编组回XML文档的方法。JAXB同样也提供了一种从java对象生成XML Schema的方式。

里有几个重要的定义:
    编组(Marshalling)是把内存中的数据转化到存储媒介上的过程。因此在 Java 和 XML 环境中,编组就是把一些 Java 对象转化成一个(或多个) XML 文档。在数据库环境中,则是把 Java 表示的数据存入数据库。显然,编组的秘密在于把 Java 实例中的面向对象结构转化成适用于 XML 的 扁平结构,或者 RDBMS 中的关系结构(使用 Java 技术转换到 OODBMS 实际上很简单)。工作原理如下图所示
webservice cxf学习
解组(Unmarshalling) 是把数据从存储媒介转换到内存中的过程--正好与编组相反。因此需要把 XML 文档解组到 Java VM 中。这里的复杂性不是在扁平数据中,因为这不是必需的,而在于从正确的数据到正确的 Java 代码变量的映射。如果映射是错误的,就不可能正确地访问数据。当然,如果再尝试重新编组还会造成更大的问题,并且问题传播得很快。工作原理如下图所示: 
webservice cxf学习

 往返(Round-tripping)可能是最重要也最容易误解的数据绑定术语。往返用于描述从存储媒介到内存然后回到存储媒介的完整循 环。在 XML 和 Java 技术环境中,这就意味着从 XML 文档到 Java 实例变量,然后再回到 XML 文档。正确的往返要求,如果中间没有修改数据,XML 输入和 XML 输出应该是等同的。
我们还以例子来说明它的工作原理,直观点。
    第一步,创建一个Customer对象

@XmlRootElement(name="customer")   
@XmlAccessorType(XmlAccessType.FIELD)   
webservice cxf学习@XmlType(name = "")   
webservice cxf学习public class Customer {   
webservice cxf学习  
webservice cxf学习    @XmlAttribute(required = true)   
webservice cxf学习    protected String name;   
webservice cxf学习    @XmlAttribute(required = true)   
webservice cxf学习    protected int age;   
webservice cxf学习  
webservice cxf学习    /**  
webservice cxf学习     * Gets the value of the name property.  
webservice cxf学习     *   
webservice cxf学习     * @return  
webservice cxf学习     *     possible object is  
webservice cxf学习     *     {@link String }  
webservice cxf学习     *       
webservice cxf学习     */  
webservice cxf学习    public String getName() {   
webservice cxf学习        return name;   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习    /**  
webservice cxf学习     * Sets the value of the name property.  
webservice cxf学习     *   
webservice cxf学习     * @param value  
webservice cxf学习     *     allowed object is  
webservice cxf学习     *     {@link String }  
webservice cxf学习     *       
webservice cxf学习     */  
webservice cxf学习    public void setName(String value) {   
webservice cxf学习        this.name = value;   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习    /**  
webservice cxf学习     * Gets the value of the age property.  
webservice cxf学习     *   
webservice cxf学习     */  
webservice cxf学习    public int getAge() {   
webservice cxf学习        return age;   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习    /**  
webservice cxf学习     * Sets the value of the age property.  
webservice cxf学习     *   
webservice cxf学习     */  
webservice cxf学习    public void setAge(int value) {   
webservice cxf学习        this.age = value;   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习}   
webservice cxf学习


第二步,创建一个测试类

public class SoapClient {   
  
webservice cxf学习    private final static String MODEL = "com.itdcl.model";   
webservice cxf学习    public static void main(String[] args) throws ParserConfigurationException, JAXBException, TransformerException{   
webservice cxf学习  
webservice cxf学习           
webservice cxf学习        ObjectFactory factory = new ObjectFactory();   
webservice cxf学习        Customer customer = factory.createCustomer();   
webservice cxf学习        customer.setAge(20);   
webservice cxf学习        customer.setName("Josen");   
webservice cxf学习  
webservice cxf学习        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();   
webservice cxf学习        dbf.setNamespaceAware(true);   
webservice cxf学习        DocumentBuilder db = dbf.newDocumentBuilder();   
webservice cxf学习        Document doc = db.newDocument();   
webservice cxf学习  
webservice cxf学习        JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);   
webservice cxf学习        //Java对象转换成XML   
webservice cxf学习                Marshaller marshaller = jaxbContext.createMarshaller();   
webservice cxf学习        marshaller.marshal(customer, doc);   
webservice cxf学习           
webservice cxf学习        DOMSource domSource = new DOMSource(doc);   
webservice cxf学习        StringWriter writer = new StringWriter();   
webservice cxf学习        StreamResult result = new StreamResult(writer);   
webservice cxf学习        TransformerFactory tf = TransformerFactory.newInstance();   
webservice cxf学习        Transformer transformer = tf.newTransformer();   
webservice cxf学习        transformer.transform(domSource, result);   
webservice cxf学习        String xmlString = writer.toString();   
webservice cxf学习        System.out.println(xmlString);   
webservice cxf学习        //XML转换成Java对象   
webservice cxf学习        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();   
webservice cxf学习        StringReader reader = new StringReader(xmlString);   
webservice cxf学习        Customer cus = (Customer)unmarshaller.unmarshal(reader);   
webservice cxf学习        System.out.println("Age:"+cus.getAge());   
webservice cxf学习        System.out.println("Name:"+cus.getName());   
webservice cxf学习           
webservice cxf学习           
webservice cxf学习    }   
webservice cxf学习}  
webservice cxf学习



第三步,运行一个测试类,看看效果如何。Java与XML之间转换如此简单
编组操作:利用上面生成的java文件执行编组操作。
 

JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);   
//Java对象转换成XML   
webservice cxf学习              Marshaller marshaller = jaxbContext.createMarshaller();   
webservice cxf学习marshaller.marshal(customer, doc);   
webservice cxf学习  
webservice cxf学习DOMSource domSource = new DOMSource(doc);   
webservice cxf学习StringWriter writer = new StringWriter();   
webservice cxf学习StreamResult result = new StreamResult(writer);   
webservice cxf学习TransformerFactory tf = TransformerFactory.newInstance();   
webservice cxf学习Transformer transformer = tf.newTransformer();   
webservice cxf学习transformer.transform(domSource, result);   
webservice cxf学习String xmlString = writer.toString();   
webservice cxf学习System.out.println(xmlString);  
webservice cxf学习


解组操作:通过xml文件执行解组操作。

  JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);   
              Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();   
webservice cxf学习StringReader reader = new StringReader(xmlString);   
webservice cxf学习Customer cus = (Customer)unmarshaller.unmarshal(reader);   
webservice cxf学习System.out.println("Age:"+cus.getAge());   
webservice cxf学习System.out.println("Name:"+cus.getName());  
webservice cxf学习



整合Spring框架
首先,在前面基础上再导入几个spring要用到的几个.jar包:
    spring-core.jar
    spring-jdbc.jar
    spring-context.jar
    spring-orm.jar
    spring-beans.jar
    spring-tx.jar
    包导入完之后,我们还不能开如干活,配置几荐参数,便于下一步工作。
    配置CXF框架
    我的电脑->属性->高级->环境变量
    创建一个CXF_HOEM变量,值为CXF框架所在根目录,修改一下
    CLASSPATH=%CXF_HOME%/lib;PATH=%CXF_HOME%/bin;这时有会问为什么要配置这两个参数据呢,其实配置这两个参数用途与配置JAVA变量一下,在DOS窗口下直接运行java2ws,wsdl2java等可执行文件。当然你没有配置也可以进到CXF框架的bin目录下远行这个几个可执行文件。
   配置好了后,你在DOS窗口下输入java2ws,看看配置是否效。肯定没有成功,原因是使用6.0的JDK,我们还得在%JAVA_HOME%/jre/lib目录下创建一下endorsed文件夹,将jaxb-api.jar,jaxws.jar拷贝进去。现在再运一下java2ws,成功运行,配置生效了。
    基本工作做得差不多,整合spring框架正式开始:
    第一步:新一个web project,导入要用到.jar包,其实CXF利用org.apache.cxf.transport.servlet.CXFServlet来拦截所有web请求,将其配置到web.xml中。配置如下:

<web-app>   
    <context-param>   
webservice cxf学习        <param-name>contextConfigLocation</param-name>   
webservice cxf学习        <param-value>   
webservice cxf学习            /WEB-INF/classes/applicationContext-*.xml,/WEB-INF/classes/webservice.xml   
webservice cxf学习        </param-value>   
webservice cxf学习    </context-param>   
webservice cxf学习  
webservice cxf学习    <listener>   
webservice cxf学习        <listener-class>   
webservice cxf学习            org.springframework.web.context.ContextLoaderListener   
webservice cxf学习        </listener-class>   
webservice cxf学习    </listener>   
webservice cxf学习  
webservice cxf学习    [color=red]<servlet>   
webservice cxf学习        <servlet-name>CXFServlet</servlet-name>   
webservice cxf学习        <display-name>CXF Servlet</display-name>   
webservice cxf学习        <servlet-class>   
webservice cxf学习            org.apache.cxf.transport.servlet.CXFServlet   
webservice cxf学习        </servlet-class>   
webservice cxf学习        <load-on-startup>1</load-on-startup>   
webservice cxf学习    </servlet>   
webservice cxf学习  
webservice cxf学习    <servlet-mapping>   
webservice cxf学习        <servlet-name>CXFServlet</servlet-name>   
webservice cxf学习        <url-pattern>/*</url-pattern>   
webservice cxf学习    </servlet-mapping>[/color]   
webservice cxf学习</web-app>  
webservice cxf学习


注意一下绿色字体
      CXF框架配置好了,我就来开发一个WebService接口

@WebService   
     public interface IService {   
webservice cxf学习  
webservice cxf学习//public void save(@WebParam(name="info")String xml);   
webservice cxf学习public void save(@WebParam(name="dto")UserInfoDTO dto,@WebParam(name="flag")boolean flag);   
webservice cxf学习public void update(@WebParam(name="info")String xml);   
webservice cxf学习public void delete(@WebParam(name="id")int id);   
webservice cxf学习public @WebResult(name="String")String get(@WebParam(name="id")int id);   
webservice cxf学习    }  


这里面有四个方法,其中有一个涉及到对象,这一点前面一节讲到怎么处理它。放在这里是再回顾前节内容。
    创建一个WebService接口实现类

 @WebService  
   public class ServiceImpl implements IService {   
webservice cxf学习private Logger log = LoggerFactory.getLogger(ServiceImpl.class);   
webservice cxf学习  
webservice cxf学习public void delete(int id) {   
webservice cxf学习    log.info("delete id is {} user"+id);   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void save(UserInfoDTO dto,boolean flag) {   
webservice cxf学习    System.out.println("name:"+dto.getName());   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void update(String xml) {   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public String get(int id){   
webservice cxf学习    return null;   
webservice cxf学习}   
webservice cxf学习  }   
webservice cxf学习

由于本节只讲解与Spring整合,没有涉及到数据库,因就打印一下传递过来的对象内容来证明整合成功。与spring,hibernate整合后面章节会讲到,请留意后面章节。
   传递对象,当然创建对象啦

@XmlType(name="ServerUserInfo")   
  @XmlAccessorType(XmlAccessType.FIELD)   
webservice cxf学习  public class UserInfoDTO implements java.io.Serializable {   
webservice cxf学习  
webservice cxf学习private static final long serialVersionUID = -4666026219400887433L;   
webservice cxf学习private Integer id;   
webservice cxf学习private String name;   
webservice cxf学习private Integer age;   
webservice cxf学习private Integer address;   
webservice cxf学习  
webservice cxf学习public Integer getId() {   
webservice cxf学习    return id;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setId(Integer id) {   
webservice cxf学习    this.id = id;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public String getName() {   
webservice cxf学习    return name;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setName(String name) {   
webservice cxf学习    this.name = name;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public Integer getAge() {   
webservice cxf学习    return age;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setAge(Integer age) {   
webservice cxf学习    this.age = age;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public Integer getAddress() {   
webservice cxf学习    return address;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public void setAddress(Integer address) {   
webservice cxf学习    this.address = address;   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习public UserInfoDTO() {   
webservice cxf学习}   
webservice cxf学习  
webservice cxf学习   }  
webservice cxf学习

   做了这么多工作,有人又会问,怎么现在做的与spring框架就没一点联系,呵呵,确实是这样。开戏开场了,利用Spring来发布WebService接口:

 <?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
webservice cxf学习    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
webservice cxf学习    [color=red]xmlns:jaxws="http://cxf.apache.org/jaxws"[/color]   
webservice cxf学习    xsi:schemaLocation="   
webservice cxf学习        http://www.springframework.org/schema/beans    
webservice cxf学习        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
webservice cxf学习        http://cxf.apache.org/jaxws    
webservice cxf学习        http://cxf.apache.org/schemas/jaxws.xsd">   
webservice cxf学习    [color=red]   
webservice cxf学习        <!--导入与CXF框架有关的xml-->   
webservice cxf学习        <import resource="classpath:META-INF/cxf/cxf.xml" />   
webservice cxf学习    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />   
webservice cxf学习    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />[/color]   
webservice cxf学习  
webservice cxf学习        <!--布布WebService接口-->   
webservice cxf学习    <jaxws:endpoint id="service"  
webservice cxf学习        implementor="com.itdcl.service.ServiceImpl" address="/Service">   
webservice cxf学习           
webservice cxf学习    </jaxws:endpoint>   
webservice cxf学习</beans>  
webservice cxf学习


服务端开发工作基本结束。现在打包部署到Tomcat6.0.18(本人目前使用的测试服务器,你当然可以使用别的服务器)
    服务器启动完成后,打开浏览器在地址栏中输入http://localhost:port/project name/Service?wsdl看看接口是否发成功。
    接下来就是开发一个客户端了。
    另建一个web project,现在前面的参数配置要起作用了,cmd进入DOS环境下输入wsdl2java -p com.itdcl.service(自定义包名) http://localhost:port/project name/Service?wsdl(前提是服务器没停止)
    敲击Enter,wsdl2java工具帮你将发布出来的wsdl文件转换成webservice接口,到指定目录下将com.itdcl.service拷到刚才另建的web project的src目录下。
    现在,我们就来创建一个客户端程序:

 public class SampleClient {   
  
webservice cxf学习ublic static void main(String[] args) {   
webservice cxf学习ApplicationContext context = new ClassPathXmlApplicationContext(   
webservice cxf学习        "beans.xml");   
webservice cxf学习     
webservice cxf学习 IService service = (IService)context.getBean("service");   
webservice cxf学习 ServerUserInfo userInfo = new ServerUserInfo();   
webservice cxf学习 userInfo.setAddress(1);   
webservice cxf学习 userInfo.setAge(100);   
webservice cxf学习 userInfo.setName("Jason");   
webservice cxf学习  
webservice cxf学习 service.save(userInfo,true);   
webservice cxf学习 service.delete(1);   
webservice cxf学习  
webservice cxf学习  
webservice cxf学习 }  
webservice cxf学习

看得仔细的朋友就会问了,ServerUserInfo 这个类那来的,你进到com.itdcl.service目录下就会看到,是WebService发布出来的。
    到目前为止,客户端还没有完成,你没有看到程序中ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");这个bean.xml就是spring框架来注删除WebService接口的。好啦,创建一个bean.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>   
  <beans xmlns="http://www.springframework.org/schema/beans"  
webservice cxf学习xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
webservice cxf学习[color=red]xmlns:jaxws="http://cxf.apache.org/jaxws[/color]"  
webservice cxf学习xsi:schemaLocation="   
webservice cxf学习    http://www.springframework.org/schema/beans    
webservice cxf学习    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
webservice cxf学习    [color=red]http://cxf.apache.org/jaxws    
webservice cxf学习    http://cxf.apache.org/schemas/jaxws.xsd[/color]">   
webservice cxf学习<jaxws:client id="service"  
webservice cxf学习    address="http://localhost:9999/cxf/Service"  
webservice cxf学习    serviceClass="com.itdcl.service.IService" />   
webservice cxf学习  </beans>  
webservice cxf学习


这一节我们来探讨一下WebService安全问题,如果所有系统都运行在一个封闭的局域网内,那么可以不考虑网络攻击,拒绝服务,消息篡改,窃取等问题。但通常情况都接入互联网,那么我就得考虑信息安全问题,像前面那样直接将消息裸传,肯定不行。那么,我们就得给消息加密。CXF可以结合WSS4J来对消息安全进行管理,可以使用令牌,X.509认证对消息头或内容进行加密。这节我只对令牌加密做一个简单的描述,我们还以Demo的形式来讲解一下。
    这个Demo是在CXF+Spring+Hibernate的基础修改而成。在这里我只针对修改的东西进行讲解。

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
webservice cxf学习    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
webservice cxf学习    xmlns:jaxws="http://cxf.apache.org/jaxws"  
webservice cxf学习    xsi:schemaLocation="   
webservice cxf学习        http://www.springframework.org/schema/beans    
webservice cxf学习        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
webservice cxf学习        http://cxf.apache.org/jaxws    
webservice cxf学习        http://cxf.apache.org/schemas/jaxws.xsd">   
webservice cxf学习    <import resource="classpath:META-INF/cxf/cxf.xml" />   
webservice cxf学习    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />   
webservice cxf学习    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />   
webservice cxf学习  
webservice cxf学习  
webservice cxf学习    <jaxws:endpoint id="service"  
webservice cxf学习        implementor="com.itdcl.service.ServiceImpl" address="/Service">   
webservice cxf学习        <jaxws:inInterceptors>   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.interceptor.LoggingInInterceptor" />   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">   
webservice cxf学习                <constructor-arg>   
webservice cxf学习                    <map>   
webservice cxf学习                        <entry key="action" value="UsernameToken" />   
webservice cxf学习                        <entry key="passwordType"  
webservice cxf学习                            value="PasswordText" />   
webservice cxf学习                        <entry key="user" value="cxfServer" />   
webservice cxf学习                        <entry key="passwordCallbackRef">   
webservice cxf学习                            <ref bean="serverPasswordCallback" />   
webservice cxf学习                        </entry>   
webservice cxf学习                    </map>   
webservice cxf学习                </constructor-arg>   
webservice cxf学习            </bean>   
webservice cxf学习        </jaxws:inInterceptors>   
webservice cxf学习    </jaxws:endpoint>   
webservice cxf学习  
webservice cxf学习    <bean id="serverPasswordCallback"  
webservice cxf学习        class="com.itdcl.ws.ServerPasswordCallback" />   
webservice cxf学习  
webservice cxf学习</beans>  
webservice cxf学习

action:UsernameToken指使用用户令牌
    passwordType:PasswordText指密码加密策略,这里直接文本
    user:cxfServer指别名
    passwordCallBackRef:serverPasswordCallback指消息验证
 

package com.itdcl.ws;   
  
webservice cxf学习import java.io.IOException;   
webservice cxf学习  
webservice cxf学习import javax.security.auth.callback.Callback;   
webservice cxf学习import javax.security.auth.callback.CallbackHandler;   
webservice cxf学习import javax.security.auth.callback.UnsupportedCallbackException;   
webservice cxf学习  
webservice cxf学习import org.apache.ws.security.WSPasswordCallback;   
webservice cxf学习  
webservice cxf学习public class ServerPasswordCallback implements CallbackHandler {   
webservice cxf学习  
webservice cxf学习    public void handle(Callback[] callbacks) throws IOException,   
webservice cxf学习            UnsupportedCallbackException {   
webservice cxf学习        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];   
webservice cxf学习        String pw = pc.getPassword();   
webservice cxf学习        String idf = pc.getIdentifier();   
webservice cxf学习        System.out.println("password:"+pw);   
webservice cxf学习        System.out.println("identifier:"+idf);   
webservice cxf学习        if (pw.equals("josen") && idf.equals("admin")) {   
webservice cxf学习            // 验证通过   
webservice cxf学习        } else {   
webservice cxf学习            throw new SecurityException("验证失败");   
webservice cxf学习        }   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习}  
webservice cxf学习

消息验证类通过实现CallbackHandler接口,实现handle方法来进行用户认证。
那么,客户端又怎样来验证消息是否确呢。

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
webservice cxf学习    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
webservice cxf学习    xmlns:jaxws="http://cxf.apache.org/jaxws"  
webservice cxf学习    xsi:schemaLocation="   
webservice cxf学习        http://www.springframework.org/schema/beans    
webservice cxf学习        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
webservice cxf学习        http://cxf.apache.org/jaxws    
webservice cxf学习        http://cxf.apache.org/schemas/jaxws.xsd">   
webservice cxf学习  
webservice cxf学习    <jaxws:client id="service"  
webservice cxf学习        address="http://localhost:9999/cxf/Service"  
webservice cxf学习        serviceClass="com.itdcl.service.IService">   
webservice cxf学习        <jaxws:outInterceptors>   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.interceptor.LoggingOutInterceptor" />   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />   
webservice cxf学习            <bean   
webservice cxf学习                class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">   
webservice cxf学习                <constructor-arg>   
webservice cxf学习                    <map>   
webservice cxf学习                        <entry key="action" value="UsernameToken" />   
webservice cxf学习                        <entry key="passwordType"  
webservice cxf学习                            value="PasswordText" />   
webservice cxf学习                        <entry key="user" value="cxfClient" />   
webservice cxf学习                        <entry key="passwordCallbackRef">   
webservice cxf学习                            <ref bean="clientPasswordCallback" />   
webservice cxf学习                        </entry>   
webservice cxf学习                    </map>   
webservice cxf学习                </constructor-arg>   
webservice cxf学习            </bean>   
webservice cxf学习        </jaxws:outInterceptors>   
webservice cxf学习    </jaxws:client>   
webservice cxf学习  
webservice cxf学习    <bean id="clientPasswordCallback"  
webservice cxf学习        class="com.itdcl.ws.ClientPasswordCallback" />   
webservice cxf学习</beans>  
webservice cxf学习

客户端在发送SOAP时对消息对认证,策略跟服务端一样。但是认证类有所区别:

package com.itdcl.ws;   
  
webservice cxf学习import java.io.IOException;   
webservice cxf学习  
webservice cxf学习import javax.security.auth.callback.Callback;   
webservice cxf学习import javax.security.auth.callback.CallbackHandler;   
webservice cxf学习import javax.security.auth.callback.UnsupportedCallbackException;   
webservice cxf学习  
webservice cxf学习import org.apache.ws.security.WSPasswordCallback;   
webservice cxf学习  
webservice cxf学习public class ClientPasswordCallback implements CallbackHandler {   
webservice cxf学习  
webservice cxf学习    public void handle(Callback[] callbacks) throws IOException,   
webservice cxf学习            UnsupportedCallbackException {   
webservice cxf学习        for(int i=0;i<callbacks.length;i++)   
webservice cxf学习        {   
webservice cxf学习             WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];   
webservice cxf学习             pc.setPassword("josen");   
webservice cxf学习             pc.setIdentifier("admin");   
webservice cxf学习        }   
webservice cxf学习    }   
webservice cxf学习  
webservice cxf学习}  

客户端在发送消息,设置好用户名和密码。服务端用相应的用户名和密码进行验证。

     令牌验证就如此简单。

上一篇:Esxi6.7 修改时区及时间


下一篇:java 写一个webservice接口(部署到Tomcat下)