本文介绍了通过cfx_2.3.2的原理,和spring整合的过程,以及webservice的基本认证,客户端代码的调用,xml传递对象。入门的不错教程哦,绝对值得一看。
第一步:新建一个webservice接口
@WebService 
public interface IHelloWorld { 
//@WebParam给参数命名,提高可代码可读性。此项可选 
public String sayHi(@WebParam(name="text") String text); 
通过注解@WebService申明为webservice接口
第二步,实现WebService接口
@WebService 
public class HelloWorldImpl implements IHelloWorld { 
public String sayHi(String name) { 
System.out.println("sayHello is called by " + name); 
return "Hello " + name; 
第三步,创建服务端
public class Server { 
private Server(){ 
IHelloWorld helloWorld = new HelloWorldImpl(); 
//创建WebService服务工厂 
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); 
/
/注册WebService接口 
factory.setServiceClass(IHelloWorld.class); 
//发布接口 
factory.setAddress("localhost:9000/HelloWorld"); 
factory.setServiceBean(helloWorld); 
//创建WebService 
}; 
public static void main(String[] args) throws InterruptedException{ 
//启动服务端 
new Server(); 
System.out.println("Server ready "); 
//休眠一分钟,便于测试 
Thread.sleep(1000*60); 
System.out.println("Server exit "); 
第四步,创建客户端
public class Client { 
private Client(){}; 
public static void main(String[] args){ 
/
/创建WebService客户端代理工厂 
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 
//注册WebService接口 
factory.setServiceClass(HelloWorld.class); 
//设置WebService地址 
factory.setAddress("localhost:9000/HelloWorld");       
IHelloWorld iHelloWorld = (ate(); 
System.out.println("invoke webservice"); 
System.out.println("message context is:"+iHelloWorld.sayHi("Josen")); 
首先,运行服务端程序
其次,打开浏览器,在地址栏中输入localhost:9000/HelloWorld?wsdl(因为cxf自带了一个jetty服务器),查看接口是否发布成功,如里浏览器页面显示下面内容,证明接口发布成功
本文所引用的资源主要包括两类,一类是Web服务的技术资源网站,包含了大量Web服务的技术信息,另一类是Web服务“stack"系列技术规范,他们是一个整体的技术体系,包括UDDI、SOAP、WSDL、XML等。本文的最后给出了这些资源的链接,有兴趣的读者可以通过这些资源链接到所需的内容。
其中,绿部分是先前已经定义好的并且广
泛使用的传输层和网络层的标准: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所定义的类型来定义整个消息的数据结构。
* Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
* PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这
些操作可以由一个或多个服务访问点来支持。
* Binding - 特定端口类型的具体协议和数据格式规范的绑定。 调用webservice服务
* Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
* Service - 相关服务访问点的集合。
大家可以参考下图,来理解一下WSDL文档的结构组织:
其中,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"   
targetNamespace="example/stockquote.wsdl" 
xmlns:tns="example/stockquote.wsdl" 
xmlns:xsd1="example/stockquote.xsd" 
xmlns:soap="/wsdl/soap/" 
xmlns="/wsdl/"> 
<types> 
<schema targetNamespace="example/stockquote.xsd" 
xmlns="/1999/XMLSchema"> 
<element name="TradePriceRequest"> 
<complexType> 
<all> 
<element name="tickerSymbol" type="string"/> 
</all> 
</complexType> 
</element> 
<element name="TradePriceResult"> 
<complexType> 
<all> 
<element name="price" type="float"/> 
</all> 
</complexType> 
</element> 
</schema> 
</types> 
上面这部分是数据类型的定义,其中为定义了两个元素的结构:
* TradePriceRequest(交易价格请求): 将该元素定义为包含一个字符串元素(tickerSymbol)的复合类型元素。
* TradePriceResult(交易价格): 将该元素定义为一个包含一个浮点数元素(price)的复合类型元素。
message name="GetLastTradePriceInput"> 
<part name="body" element="xsd1:TradePriceRequest"/> 
</message> 
<message name="GetLastTradePriceOutput"> 
<part name="body" element="xsd1:TradePriceResult"/> 
</message> 
这部分是消息格式的抽象定义,其中定义了两个消息格式:
* GetlastTradePriceInput(获取最后交易价格的请求消息格式): 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceRequest。(前面已经
定义过了)
* GetLastTradePriceOutput(获取最后交易价格的响应消息格式) : 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceResult。(前面已经定义过了)
<portType name="StockQuotePortType"> 
<operation name="GetLastTradePrice"> 
<input message="tns:GetLastTradePriceInput"/> 
<output message="tns:GetLastTradePriceOutput"/> 
</operation> 
</portType> 
这部分定义了服务访问点的调用模式的类型,表明StockQuoteService的某个入口类型是请求/响应模
式,请求消息是GetlastTradePriceInput,而响应消息是GetLastTradePriceOutput。
binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType"> 
<soap:binding transport="/soap/http"/> 
<operation name="GetLastTradePrice"> 
<soap:operation soapAction="example/GetLastTradePrice"/> 
<input> 
<soap:body use="literal" namespace="example/stockquote.xsd" 
encodingStyle="/soap/encoding/"/> 
</input> 
<output> 
<soap:body use="literal" namespace="example/stockquote.xsd" 
encodingStyle="/soap/encoding/"/> 
</output> 
</soap:operation> 
</operation> 
</soap:binding> 
</binding> 
这部分将服务访问点的抽象定义与SOAP HTTP绑定,描述如何通过SOAP/HTTP来访问按照前面描述的访问入口点类型部署的访问入口。其中规定了在具体SOAP调用时,应当使用的 soapAction是"example/GetLastTradePrice",而请求/响应消息的编码风格都应当采用SOAP 规范默认定义的编码风格" /soap/encoding/"。
<service name="StockQuoteService"> 
<documentation>股票查询服务</documentation>   
<port name="StockQuotePort" binding="tns:StockQuoteBinding"> 
<soap:address location="example/stockquote"/> 
</port> 
</service> 
</definitions> 
这部分是具体的Web服务的定义,在这个名为StockQuoteService的Web服务中,提供了一个服务访问入口,访问地址是"example/stockquote",使用的消息模式是由前面的binding所定义的。
按照这个WSDL文档的描述,在具体Web服务的使用中,具体发生的SOAP交互可能如下面所示:
SOAP消息请求:
POST /StockQuote HTTP/1.1 
Host: example 
Content-Type: text/xml; charset="utf-8" 
Content-Length: nnnn 
SOAPAction: "example/GetLastTradePrice" 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="/soap/envelope/" 
SOAP-ENV:encodingStyle="/soap/encoding/"> 
<SOAP-ENV:Body> 
<m:T

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。