JAVA 用 Apache CXF 调用 .NET 服务端 WebService
Web Service涉及的相关概念和基础知识不赘述了,想了解的请看这篇文章:http://blog.csdn.net/shb_derek/article/details/8018287
下面从头开始介绍怎样编写JAVA代码来调用Web Service:
1、首先去官网(http://cxf.apache.org/download.html)下载Apache CXF,选择最新版本的 apache-cxf-2.7.0.zip 下载(注:该本版本用jdk1.6编译,所以楼下报错的朋友有可能是jdk版本的原因)。
2、下载到本地后,将文件解压缩,可以看到有bin、docs、lib、samples等目录:
bin中存放的是批处理文件,一会儿需要用到其中的wsdl2java.bat文件来生成Web Service客户端调用代码;lib中存放的是开发Web Service需要用到的jar包(本例中引入部分jar包即可,不需要全部引入);samples中是用CXF开发WebService的例子代码,如果还不熟悉建议看看以java_first开头的五个例子,相信看完后上手会很快。
3、网上找了个.NET编写的Web Service天气预报的服务端(http://www.webxml.com.cn/WebServices/ChinaZipSearchWebService.asmx),提供的WSDL链接:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
4、打开CMD命令行窗口,切换到apache-cxf-2.7.0/bin目录下,输入命令:wsdl2java -p cn.com.webxml -d f:/ http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
-p 表示生成的JAVA客户端调用代码的包路径;-d 表示生成在本地哪个目录下(本例为F盘根目录); 最后一个参数为WSDL文件路径(也可以是本地文件),关于命令参数的具体内容可以参考:https://cwiki.apache.org/CXF20DOC/wsdl-to-java.html。如果亲自实践,可以看到命令行中会报如下错误,预期的代码并没有生成:
出错的原因从命令行反馈的信息大致可以判断出第44行和85行有错误。
5、既然有错误,就得想办法解决。浏览器中CTRL+S直接将WSDL的内容保存到本地(本例中保存文件名为weather.wsdl)并注释掉44和85行的<s:element ref="s:schema" />,然后将4步骤中的URL替换成weather.wsdl:wsdl2java -p cn.com.webxml -d f:/ weather.wsdl,可以看到CMD中没有报错并且F盘下多了个cn文件夹,里面有很多java文件,这表明第一项工作已完成。
6、Eclipse中新建JAVA工程,导入部分jar包,并拷贝上步生成的cn文件夹到src下如下图:
注释掉WeatherWebService.java中存在错误信息的三个构造方法,这样Web Service客户端调用代码就算搞定了。
7、将之前保存到本地的weather.wsdl文件拷贝到src下,编写测试代码:
- public class WeatherTest {
- public static void main(String[] args) throws Exception {
- java.net.URL wsdlLocation = ClassLoader.getSystemResource("weather.wsdl");
- JaxWsDynamicClientFactory dcf =JaxWsDynamicClientFactory.newInstance();
- //方式1. 指定classpath下的WSDL文件
- org.apache.cxf.endpoint.Client client = dcf.createClient(wsdlLocation);
- //方式2. 指定WSDL文件的绝对路径
- //dcf.createClient("D:/apache-cxf-2.7.0/bin/weather.wsdl");
- Object[] provinces = client.invoke("getSupportProvince");
- if(provinces != null && provinces.length > 0) {
- for(Object province : provinces) {
- System.out.println(((ArrayOfString)province).getString());
- }
- }
- Object[] citys = client.invoke("getSupportCity","浙江");
- if(citys != null && citys.length > 0) {
- for(Object city : citys) {
- System.out.println(((ArrayOfString)city).getString());
- }
- }
- Object[] weathers = client.invoke("getWeatherbyCityName", "杭州");
- if(weathers != null && weathers.length > 0) {
- for(Object weather : weathers) {
- System.out.println(((ArrayOfString)weather).getString());
- }
- }
- }
- }
public class WeatherTest {
public static void main(String[] args) throws Exception {
java.net.URL wsdlLocation = ClassLoader.getSystemResource("weather.wsdl");
JaxWsDynamicClientFactory dcf =JaxWsDynamicClientFactory.newInstance();
//方式1. 指定classpath下的WSDL文件
org.apache.cxf.endpoint.Client client = dcf.createClient(wsdlLocation);
//方式2. 指定WSDL文件的绝对路径
//dcf.createClient("D:/apache-cxf-2.7.0/bin/weather.wsdl");
Object[] provinces = client.invoke("getSupportProvince");
if(provinces != null && provinces.length > 0) {
for(Object province : provinces) {
System.out.println(((ArrayOfString)province).getString());
}
}
Object[] citys = client.invoke("getSupportCity","浙江");
if(citys != null && citys.length > 0) {
for(Object city : citys) {
System.out.println(((ArrayOfString)city).getString());
}
}
Object[] weathers = client.invoke("getWeatherbyCityName", "杭州");
if(weathers != null && weathers.length > 0) {
for(Object weather : weathers) {
System.out.println(((ArrayOfString)weather).getString());
}
}
}
}
8、Run As -> Java Appliaction,控制台输出天气信息,OK!