我的上一篇blog里提到,"系列后面的这几篇(WSDL解析跟SAAJ的使用)可当会有点理论化了,初看的话可能会感觉有点晦涩... ",确实是这样的,不过,我想前面的系列文章因为是针对项目的总结,所以不可能对所汲及到的技术讨论的面面俱到.所以,在这篇blog里,基于之前在系列里讨论的WSDL4J跟Castor XML Schema(这个在前面没有怎么提到)写一个简单的Web服务解析工具,提供解析Web服务的功能,能够解析大部分与XML Schema规范兼容的Web服务,主要的目的是用来学习WSDL4J,Castor这两个工具及如何使用它们解析一个Web服务.运行.这个小实例必须:
<?
xml version="1.0" encoding="UTF-8"
?>
<
wsdl:definitions
xmlns:wsdl
="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap11
="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap12
="http://www.w3.org/2003/05/soap-envelope"
xmlns:soapenc11
="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soapenc12
="http://www.w3.org/2003/05/soap-encoding"
xmlns:tns
="http://weather.cactus.org"
xmlns:wsdlsoap
="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
targetNamespace
="http://weather.cactus.org"
>
<
wsdl:types
>
<
xsd:schema
targetNamespace
="http://weather.cactus.org"
elementFormDefault
="qualified"
attributeFormDefault
="qualified"
>
<
xsd:element
name
="getAllWeatherInfo"
>
<
xsd:complexType
/>
</
xsd:element
>
<
xsd:complexType
name
="ArrayOfWeather"
>
<
xsd:sequence
>
<
xsd:element
name
="Weather"
type
="tns:Weather"
nillable
="true"
minOccurs
="0"
maxOccurs
="unbounded"
/>
</
xsd:sequence
>
</
xsd:complexType
>
<
xsd:complexType
name
="Weather"
>
<
xsd:sequence
>
<
xsd:element
name
="ambientAirQuality"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="city"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="highestTemperature"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="highestWindPower"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="lowestTemperature"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="lowestWindPower"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="state"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
<
xsd:element
name
="windDirection"
type
="xsd:string"
minOccurs
="0"
nillable
="true"
/>
</
xsd:sequence
>
</
xsd:complexType
>
<
xsd:element
name
="getAllWeatherInfoResponse"
>
<
xsd:complexType
>
<
xsd:sequence
>
<
xsd:element
name
="out"
type
="tns:ArrayOfWeather"
nillable
="true"
minOccurs
="1"
maxOccurs
="1"
/>
</
xsd:sequence
>
</
xsd:complexType
>
</
xsd:element
>
<
xsd:element
name
="getWeatherInfomationByCity"
>
<
xsd:complexType
>
<
xsd:sequence
>
<
xsd:element
name
="in0"
type
="xsd:string"
nillable
="true"
minOccurs
="1"
maxOccurs
="1"
/>
</
xsd:sequence
>
</
xsd:complexType
>
</
xsd:element
>
<
xsd:element
name
="getWeatherInfomationByCityResponse"
>
<
xsd:complexType
>
<
xsd:sequence
>
<
xsd:element
name
="out"
type
="tns:Weather"
nillable
="true"
minOccurs
="1"
maxOccurs
="1"
/>
</
xsd:sequence
>
</
xsd:complexType
>
</
xsd:element
>
</
xsd:schema
>
</
wsdl:types
>
<
wsdl:message
name
="getAllWeatherInfoResponse"
>
<
wsdl:part
element
="tns:getAllWeatherInfoResponse"
name
="parameters"
/>
</
wsdl:message
>
<
wsdl:message
name
="getAllWeatherInfoRequest"
>
<
wsdl:part
element
="tns:getAllWeatherInfo"
name
="parameters"
/>
</
wsdl:message
>
<
wsdl:message
name
="getWeatherInfomationByCityResponse"
>
<
wsdl:part
element
="tns:getWeatherInfomationByCityResponse"
name
="parameters"
/>
</
wsdl:message
>
<
wsdl:message
name
="getWeatherInfomationByCityRequest"
>
<
wsdl:part
element
="tns:getWeatherInfomationByCity"
name
="parameters"
/>
</
wsdl:message
>
<
wsdl:portType
name
="WeatherServicePortType"
>
<
wsdl:operation
name
="getAllWeatherInfo"
>
<
wsdl:input
message
="tns:getAllWeatherInfoRequest"
name
="getAllWeatherInfoRequest"
/>
<
wsdl:output
message
="tns:getAllWeatherInfoResponse"
name
="getAllWeatherInfoResponse"
/>
</
wsdl:operation
>
<
wsdl:operation
name
="getWeatherInfomationByCity"
>
<
wsdl:input
message
="tns:getWeatherInfomationByCityRequest"
name
="getWeatherInfomationByCityRequest"
/>
<
wsdl:output
message
="tns:getWeatherInfomationByCityResponse"
name
="getWeatherInfomationByCityResponse"
/>
</
wsdl:operation
>
</
wsdl:portType
>
<
wsdl:binding
name
="WeatherServiceHttpBinding"
type
="tns:WeatherServicePortType"
>
<
wsdlsoap:binding
style
="document"
transport
="http://schemas.xmlsoap.org/soap/http"
/>
<
wsdl:operation
name
="getAllWeatherInfo"
>
<
wsdlsoap:operation
soapAction
=""
/>
<
wsdl:input
name
="getAllWeatherInfoRequest"
>
<
wsdlsoap:body
use
="literal"
/>
</
wsdl:input
>
<
wsdl:output
name
="getAllWeatherInfoResponse"
>
<
wsdlsoap:body
use
="literal"
/>
</
wsdl:output
>
</
wsdl:operation
>
<
wsdl:operation
name
="getWeatherInfomationByCity"
>
<
wsdlsoap:operation
soapAction
=""
/>
<
wsdl:input
name
="getWeatherInfomationByCityRequest"
>
<
wsdlsoap:body
use
="literal"
/>
</
wsdl:input
>
<
wsdl:output
name
="getWeatherInfomationByCityResponse"
>
<
wsdlsoap:body
use
="literal"
/>
</
wsdl:output
>
</
wsdl:operation
>
</
wsdl:binding
>
<
wsdl:service
name
="WeatherService"
>
<
wsdl:port
binding
="tns:WeatherServiceHttpBinding"
name
="WeatherServiceHttpPort"
>
<
wsdlsoap:address
location
="http://202.118.22.171:8080/weather/services/WeatherService"
/>
</
wsdl:port
>
</
wsdl:service
>
</
wsdl:definitions
>
图2,构建完WSDL的castor Schema
图8 把服务所有操作及参数都列出了
1下载例子原代码及示例Web服务.
大家可以到我的资源去下载本程序
(已经上传,下载使用过程请参考下一篇blog:http://blog.youkuaiyun.com/lin_bei/archive/2007/05/02/1594868.aspx
).
对将要解析的Web服务的有关说明:
首先,本小程序的输入数据,即将要被解析的Web 服务,可以是网络上任何可访问的Web
服务,但有个前提是,Web服务所对应的WSDL 文档中的schema定义应该符合W3C,因为我也试过很多外国网站那些Web服务,有些不可以正确的解析,原因就是那些WSDL文档的schema有些写的并不规范,所以解析会发生异常.
应该这时候有人可能会问上哪找这些服务呢,我想对Web服务感兴趣的人对Xmethod网站应该很熟悉吧,它是国外最有名的提供Web服务的站点,我们团队开发的Web服务搜索与执行引擎跟这个网站很相似,它上面有在各种平台下开发的可供访问的Web服务:
http://www.xmethods.net/ve2/index.po
,所以说,现在有两种方法来测试本小程序:
1) 为了方便,为大家提供了一个可测试的Web服务,我在写这个程序时也是用这个 Web服务来测试.打开下载后的文件夹,里面有个”基于Xfire的Web服务 布署到tomcat后的文件”的子文件夹.这就是一个相对简单的天气服务.布署很简单,只需把它放到您的Tomcat服务器下的webapps目录下就行了,这时候通过浏览器输入:
http://localhost:8080/weather/services/WeatherService?wsdl
就可以取得WSDL文档,把这个URL复制到WSClient.java类里.
2) 1)是可选的,因为您可以像我在前面说的那样,访问:
http://www.xmethods.net/ve2/index.po
网站,在这个页面里,可以选择一个Web服务,然后取得WSDL文档的URL,复制到WSClient.java类里.进行远程连接解析.您也可以使用别的现成的Web服务来解析.
为了使分析问题更加简单,现在使用第1)种方法的Web服务.
2.运行程序:

如上图所示,WSCient是一个带有main函数的类,在Eclipse下运行它,就可以在控制台下查看到如下截图的一系列结果.
3.待测试的wsdl文档如下所示:
































































































这个天气服务有两个操作:
1.获取当前所有城市的天气信息。(getAllWeatherInfo())返回的是天气对象(以参数的形式返回)
2.获取某个城市的天气信息。(getWeatherInfomationByCity(String city))返回的是天气对象(以参数的形式返回)
具体地过程就不在这里分析,大家可以对照着代码里面的注释跟打印信息进行分析.
我把程序运行后的贴图,贴出来:
图1接收WSDL文档并打印Schema信息


图3 开始构建Web服务对象(1)

图4 构建Web服务对象(2)

图5 构建Web服务对象(3)

图6 构建Web服务对象(4)

图7 成功构建完Web服务对象
