自己动手编写Web服务工具[解析]

我的上一篇blog里提到,"系列后面的这几篇(WSDL解析跟SAAJ的使用)可当会有点理论化了,初看的话可能会感觉有点晦涩...",确实是这样的,不过,我想前面的系列文章因为是针对项目的总结,所以不可能对所汲及到的技术讨论的面面俱到.所以,在这篇blog里,基于之前在系列里讨论的WSDL4J跟Castor XML Schema(这个在前面没有怎么提到)写一个简单的Web服务解析工具,提供解析Web服务的功能,能够解析大部分与XML Schema规范兼容的Web服务,主要的目的是用来学习WSDL4J,Castor这两个工具及如何使用它们解析一个Web服务.运行.这个小实例必须:

1下载例子原代码及示例Web服务.

大家可以到我的资源去下载本程序
(已经上传,下载使用过程请参考下一篇blog:http://blog.****.net/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.运行程序:
自己动手编写Web服务工具[解析]
如上图所示,WSCient是一个带有main函数的类,在Eclipse下运行它,就可以在控制台下查看到如下截图的一系列结果.
3.待测试的wsdl文档如下所示:
自己动手编写Web服务工具[解析]<?xmlversion="1.0"encoding="UTF-8"?>
自己动手编写Web服务工具[解析]
<wsdl:definitionsxmlns: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">
自己动手编写Web服务工具[解析]
<wsdl:types>
自己动手编写Web服务工具[解析]
<xsd:schematargetNamespace="http://weather.cactus.org"elementFormDefault="qualified"attributeFormDefault="qualified">
自己动手编写Web服务工具[解析]
<xsd:elementname="getAllWeatherInfo">
自己动手编写Web服务工具[解析]
<xsd:complexType/>
自己动手编写Web服务工具[解析]
</xsd:element>
自己动手编写Web服务工具[解析]
<xsd:complexTypename="ArrayOfWeather">
自己动手编写Web服务工具[解析]
<xsd:sequence>
自己动手编写Web服务工具[解析]
<xsd:elementname="Weather"type="tns:Weather"nillable="true"minOccurs="0"maxOccurs="unbounded"/>
自己动手编写Web服务工具[解析]
</xsd:sequence>
自己动手编写Web服务工具[解析]
</xsd:complexType>
自己动手编写Web服务工具[解析]
<xsd:complexTypename="Weather">
自己动手编写Web服务工具[解析]
<xsd:sequence>
自己动手编写Web服务工具[解析]
<xsd:elementname="ambientAirQuality"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="city"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="highestTemperature"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="highestWindPower"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="lowestTemperature"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="lowestWindPower"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="state"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
<xsd:elementname="windDirection"type="xsd:string"minOccurs="0"nillable="true"/>
自己动手编写Web服务工具[解析]
</xsd:sequence>
自己动手编写Web服务工具[解析]
</xsd:complexType>
自己动手编写Web服务工具[解析]
<xsd:elementname="getAllWeatherInfoResponse">
自己动手编写Web服务工具[解析]
<xsd:complexType>
自己动手编写Web服务工具[解析]
<xsd:sequence>
自己动手编写Web服务工具[解析]
<xsd:elementname="out"type="tns:ArrayOfWeather"nillable="true"minOccurs="1"maxOccurs="1"/>
自己动手编写Web服务工具[解析]
</xsd:sequence>
自己动手编写Web服务工具[解析]
</xsd:complexType>
自己动手编写Web服务工具[解析]
</xsd:element>
自己动手编写Web服务工具[解析]
<xsd:elementname="getWeatherInfomationByCity">
自己动手编写Web服务工具[解析]
<xsd:complexType>
自己动手编写Web服务工具[解析]
<xsd:sequence>
自己动手编写Web服务工具[解析]
<xsd:elementname="in0"type="xsd:string"nillable="true"minOccurs="1"maxOccurs="1"/>
自己动手编写Web服务工具[解析]
</xsd:sequence>
自己动手编写Web服务工具[解析]
</xsd:complexType>
自己动手编写Web服务工具[解析]
</xsd:element>
自己动手编写Web服务工具[解析]
<xsd:elementname="getWeatherInfomationByCityResponse">
自己动手编写Web服务工具[解析]
<xsd:complexType>
自己动手编写Web服务工具[解析]
<xsd:sequence>
自己动手编写Web服务工具[解析]
<xsd:elementname="out"type="tns:Weather"nillable="true"minOccurs="1"maxOccurs="1"/>
自己动手编写Web服务工具[解析]
</xsd:sequence>
自己动手编写Web服务工具[解析]
</xsd:complexType>
自己动手编写Web服务工具[解析]
</xsd:element>
自己动手编写Web服务工具[解析]
</xsd:schema>
自己动手编写Web服务工具[解析]
</wsdl:types>
自己动手编写Web服务工具[解析]
<wsdl:messagename="getAllWeatherInfoResponse">
自己动手编写Web服务工具[解析]
<wsdl:partelement="tns:getAllWeatherInfoResponse"name="parameters"/>
自己动手编写Web服务工具[解析]
</wsdl:message>
自己动手编写Web服务工具[解析]
<wsdl:messagename="getAllWeatherInfoRequest">
自己动手编写Web服务工具[解析]
<wsdl:partelement="tns:getAllWeatherInfo"name="parameters"/>
自己动手编写Web服务工具[解析]
</wsdl:message>
自己动手编写Web服务工具[解析]
<wsdl:messagename="getWeatherInfomationByCityResponse">
自己动手编写Web服务工具[解析]
<wsdl:partelement="tns:getWeatherInfomationByCityResponse"name="parameters"/>
自己动手编写Web服务工具[解析]
</wsdl:message>
自己动手编写Web服务工具[解析]
<wsdl:messagename="getWeatherInfomationByCityRequest">
自己动手编写Web服务工具[解析]
<wsdl:partelement="tns:getWeatherInfomationByCity"name="parameters"/>
自己动手编写Web服务工具[解析]
</wsdl:message>
自己动手编写Web服务工具[解析]
<wsdl:portTypename="WeatherServicePortType">
自己动手编写Web服务工具[解析]
<wsdl:operationname="getAllWeatherInfo">
自己动手编写Web服务工具[解析]
<wsdl:inputmessage="tns:getAllWeatherInfoRequest"name="getAllWeatherInfoRequest"/>
自己动手编写Web服务工具[解析]
<wsdl:outputmessage="tns:getAllWeatherInfoResponse"name="getAllWeatherInfoResponse"/>
自己动手编写Web服务工具[解析]
</wsdl:operation>
自己动手编写Web服务工具[解析]
<wsdl:operationname="getWeatherInfomationByCity">
自己动手编写Web服务工具[解析]
<wsdl:inputmessage="tns:getWeatherInfomationByCityRequest"name="getWeatherInfomationByCityRequest"/>
自己动手编写Web服务工具[解析]
<wsdl:outputmessage="tns:getWeatherInfomationByCityResponse"name="getWeatherInfomationByCityResponse"/>
自己动手编写Web服务工具[解析]
</wsdl:operation>
自己动手编写Web服务工具[解析]
</wsdl:portType>
自己动手编写Web服务工具[解析]
<wsdl:bindingname="WeatherServiceHttpBinding"type="tns:WeatherServicePortType">
自己动手编写Web服务工具[解析]
<wsdlsoap:bindingstyle="document"transport="http://schemas.xmlsoap.org/soap/http"/>
自己动手编写Web服务工具[解析]
<wsdl:operationname="getAllWeatherInfo">
自己动手编写Web服务工具[解析]
<wsdlsoap:operationsoapAction=""/>
自己动手编写Web服务工具[解析]
<wsdl:inputname="getAllWeatherInfoRequest">
自己动手编写Web服务工具[解析]
<wsdlsoap:bodyuse="literal"/>
自己动手编写Web服务工具[解析]
</wsdl:input>
自己动手编写Web服务工具[解析]
<wsdl:outputname="getAllWeatherInfoResponse">
自己动手编写Web服务工具[解析]
<wsdlsoap:bodyuse="literal"/>
自己动手编写Web服务工具[解析]
</wsdl:output>
自己动手编写Web服务工具[解析]
</wsdl:operation>
自己动手编写Web服务工具[解析]
<wsdl:operationname="getWeatherInfomationByCity">
自己动手编写Web服务工具[解析]
<wsdlsoap:operationsoapAction=""/>
自己动手编写Web服务工具[解析]
<wsdl:inputname="getWeatherInfomationByCityRequest">
自己动手编写Web服务工具[解析]
<wsdlsoap:bodyuse="literal"/>
自己动手编写Web服务工具[解析]
</wsdl:input>
自己动手编写Web服务工具[解析]
<wsdl:outputname="getWeatherInfomationByCityResponse">
自己动手编写Web服务工具[解析]
<wsdlsoap:bodyuse="literal"/>
自己动手编写Web服务工具[解析]
</wsdl:output>
自己动手编写Web服务工具[解析]
</wsdl:operation>
自己动手编写Web服务工具[解析]
</wsdl:binding>
自己动手编写Web服务工具[解析]
<wsdl:servicename="WeatherService">
自己动手编写Web服务工具[解析]
<wsdl:portbinding="tns:WeatherServiceHttpBinding"name="WeatherServiceHttpPort">
自己动手编写Web服务工具[解析]
<wsdlsoap:addresslocation="http://202.118.22.171:8080/weather/services/WeatherService"/>
自己动手编写Web服务工具[解析]
</wsdl:port>
自己动手编写Web服务工具[解析]
</wsdl:service>
自己动手编写Web服务工具[解析]
</wsdl:definitions>
这个天气服务有两个操作:
1.获取当前所有城市的天气信息。(getAllWeatherInfo())返回的是天气对象(以参数的形式返回)
2.获取某个城市的天气信息。(getWeatherInfomationByCity(String city))返回的是天气对象(以参数的形式返回)
具体地过程就不在这里分析,大家可以对照着代码里面的注释跟打印信息进行分析.
我把程序运行后的贴图,贴出来:

自己动手编写Web服务工具[解析]

图1接收WSDL文档并打印Schema信息
自己动手编写Web服务工具[解析]图2,构建完WSDL的castor Schema
自己动手编写Web服务工具[解析]
图3 开始构建Web服务对象(1)
自己动手编写Web服务工具[解析]
图4 构建Web服务对象(2)
自己动手编写Web服务工具[解析]
图5 构建Web服务对象(3)
自己动手编写Web服务工具[解析]
图6 构建Web服务对象(4)
自己动手编写Web服务工具[解析]
图7 成功构建完Web服务对象
自己动手编写Web服务工具[解析]
8 把服务所有操作及参数都列出了