最近项目中又要调用其他系统的WebService ,同时呢本项目也需要提供webService 服务,有几年没有用CXF 、Axis2 、xfire 这三个框架了,本来想写详细点,一回想这三个框架内容实在太多,所以这里简单写下CXF、Axis2调用WebService 吧!
关于CXF AXIS2 发布webService 在另外的博客在写吧!主要是想记录和给组里其他没用的 能够尽快上手!
关于WebService 基本的概念介绍,这里就不累赘了,网上好多,原来做培训的时候写过相关文档,如果找到的话就上传到资源
这里要说一个问题:就是好多人说 写的文章排版不好,这个实在抱歉,很多时候没有注意,同时呢时间确实不同,有的认为简单就没有在注意,非常抱歉!以后会注意
最近在弄Spring Boot 和Spring Cloud ,后面如果写好了会上传......
Axis2 调用WebService有三种方式,如下:
首先需要下载axis2,我使用的是axis2-1.7.3,下载成功后解压即可
下载地址:http://axis.apache.org/axis2/java/core/
第一种: 利用wsdl2java命令反向生成WebService 的相关类
命令如下:
# cd D: \axis2-1.7.3\bin
# wsdl2java.bat -uri http://113.119.4.5:XXXX/NiLockWebService.asmx?wsdl
如天气接口
# wsdl2java.bat-uri http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
操作成功后会在bin目录下生成一个src 文件夹
把src 文件夹下面的类拷贝到项目src下 ,有一个stub结尾的类 里面可以相关调用的方法名,soapAction、方法参数等等
调用代码如下:
NLockWebServiceStub stub = new NLockWebServiceStub(); //反向生成类
//获取serviceClient 可以设置相关参数
ServiceClientserviceClient = stub._getServiceClient();
Optionsoptions = serviceClient.getOptions();
//options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE);
//设置命令空间
options.setAction("http://microsoft.com/webservices/");
//实例化对应调用方法
GPRSCMD gprscmd = new GPRSCMD();
//设置对应参数
gprscmd.setAccount(username);
gprscmd.setMd5(accPassword);
gprscmd.setJsonStr(jsonStr);
//调用返回结果
String result = stub.gPRSCMD(gprscmd).getGPRSCMDResult();
System.out.println("result:"+result);
基本的调用如上,此方法是个人认为最不容易出错的方法,但是需要我们在项目加入相关代码,比如像我的项目里需要调用的webservice 比较多,同时还需要对外提供 webservice 服务,可能就需要加入很多代码了!
第二种: 使用RPC远程过程调用
代码如下:
String url =" http://113.119.4.5:XXXX/NiLockWebService.asmx?wsdl ";
RPCServiceClient client = newRPCServiceClient();
Options options = client.getOptions();
//可以设置HttpClient
/* MultiThreadedHttpConnectionManager connManager = newMultiThreadedHttpConnectionManager();
connManager.getParams().setSoTimeout(600*1000); //10秒
connManager.getParams().setConnectionTimeout(600*1000);
HttpClient httpclient = newHttpClient(connManager);
options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpclient );
*/
EndpointReference endpoint = newEndpointReference(url);
options.setTo(endpoint);
options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE);
options.setAction("http://microsoft.com/webservices ");
// options.setTimeOutInMilliSeconds(50000000L);
// options.setProperty(HTTPConstants., 600000);
// options.setProperty(HTTPConstants.SO_TIMEOUT, 600*1000);
options.setProperty(HTTPConstants.SO_TIMEOUT, 600*1000);
Object[] obj = new Object[]{username,acc,json};
//返回值类型
Class>[] classes = new Class[] { String.class };
QName qname = new QName("http://microsoft.com/webservices/ ", "GPRSCMD");
String result = (String)client.invokeBlocking(qname, obj,classes)[0];
System.out.println("result: "+result);
}catch(AxisFault e){
e.printStackTrace();
}
如果没有返回值使用invokeRobust(opName, args) 方法
此方法比第一种方式 代码就要简洁很多,调用过程中需要注意参数问题,多个传递参数时候,服务端接收到到的参数顺序可能会发生变化,一定要注意,不然结果老是出错!
第三种: 使用document方式调用
Optionsoptions = newOptions();
// 指定调用WebService的URL
EndpointReferencetargetEPR = newEndpointReference(url);
options.setTo(targetEPR);
options.setAction("http://microsoft.com/webservice");
ServiceClientsender = newServiceClient();
sender.setOptions(options);
OMFactory omFactory = OMAbstractFactory.getOMFactory();
String tns = "http://microsoft.com/webservices ";
// 命名空间
OMNamespace namespace =omFactory.createOMNamespace(tns, "");
//指定方法
OMElement method =omFactory.createOMElement("GPRSCMD", namespace);
//指定方法的参数
OMElement usernameElement = omFactory.createOMElement("account",namespace);
usernameElement.setText(username);
OMElement md5Element = omFactory.createOMElement("md5",namespace);
md5Element.setText(accPassword);
OMElement strElement = omFactory.createOMElement("json",namespace);
strElement.setText(jsonStr);
method.addChild(usernameElement);
method.addChild(md5Element);
method.addChild(strElement);
OMElement result =sender.sendReceive(method);
System.out.println("result: "+ result);
CXF 调用WebService
下载cxf 我使用的是apache-cxf-2.7.18
进入到bin 目录使用wsdl2java 命令生成对应类
# wsdl2java.bat http://114.119.5.137:1001/NLockWebService.asmx?wsdl
执行成功后会在bin 目录下生成webservice 对应的包与类
与axis2 不同的是没有生成src 文件夹,同时cxf 会生成一堆类,如果用过cxf 编写过webservice 的都知道,cxf 生成的类看起来要比axis2 清楚很多
拷贝所有文件到项目src 下,同时需要导入cxf 相关jar
soap 类是我们调用的入口类,里面定义了具体的每一个方法和方法需要的相关参数,cxf 保留了原来参数名等,axis2 方法名与实际方法名有些不同,需要注意
//webservice 地址
String address = "http://113.119.4.5:XXXX/NiLockWebService.asmx?wsdl";
//
JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
bean.setAddress(address);
bean.setServiceClass(NLockWebServiceSoap.class);
//bean.setEndpointName(endpointName);
//bean.setWsdlLocation(wsdlURL);
NLockWebServiceSoap webServiceSoap =(NLockWebServiceSoap) bean.create();
//调用对应的方法
String result =webServiceSoap.gprscmd(username, accPassword, jsonStr);
System.out.println("result :"+result);