之前开发webservice客户端的时候遇到一个使用Axis2开发接口的厂家,查资料把Axis1和Axis2客户端的开发方式总结如下:
基于Axis1服务端的客户端实现:
/**
* 使用Axis Call Client动态调用WebService
* @param requestXml 请求报文
* @param wsdl webservice地址
* @param targetNamespace 命名空间
* @param webServiceMethod 访问的方法名
* @return
*/
public String getRespByAxisCallClient(String requestXml, String wsdl,String targetNamespace, String webServiceMethod){
String respXml = "";
try{
Service service = new Service();
Call call = (Call) service.createCall();
//设置要访问的WSDL地址
call.setTargetEndpointAddress(new URL(wsdl));
//设置要访问的方法名
call.setOperationName(new QName(wsdl,webServiceMethod));
//设置参数
call.addParameter("XMLFrom", XMLType.XSD_STRING, ParameterMode.IN);
//设置返回值类型
call.setReturnType(XMLType.XSD_STRING);
//调用服务
respXml = (String) call.invoke(new Object[] { requestXml.toString() });
}catch(Exception e){
logger.error("服务调用异常",e);
}
return respXml;
}
Call在线API:http://axis.apache.org/axis/java/apiDocs/org/apache/axis/client/Call.html
基于Axis2服务端的客户端实现: 方法一: 采用RPC的方式进行远程调用,通过URL定位告诉远程服务器需要调用的方法名、参数等,调用远程服务,获取结果。如果被调用的WebService方法有返回值,应使invokeBlocking 方法 该方法有三个参数:第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[]; 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。第三个参数表示WebService方法的 返回值类型的Class对象,参数类型为Class[]。如果被调用的WebService方法没有返回值 应使用 invokeRobust 方法。该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是 <wsdl:definitions>元素的targetNamespace属性值。方法如下:/**注意: 1、如果被调用的WebService方法有返回值,应使用invokeBlocking方法,该方法有三个参数: 第一个参数的类型是QName对象,表示要调用的方法名; 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。 第三个参数表示WebService方法的,返回值类型的Class对象,参数类型为Class[]。2、如果返回对象是String类型的字符串,参数为String.class;如果返回对象是double类型的数字,参数为double.class。3、如果被调用的WebService方法没有返回值,应使用invokeRobust方法:该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。 在开发过程中遇到以下错误: 错误一:
* 方法一:RPC调用webservice Axis2服务
* @param wsdl 接口服务端调用地址
* @param webServiceMethod 调用方法
* @param inParam 请求参数
* @param targetNamespace 命名空间
* @return
*/
public String getRespByAxisRPCClient(Map<String,Object> inParam, String wsdl,String targetNamespace, String webServiceMethod){
String responseStr = "";
RPCServiceClient serviceClient = null;
try{
//获取RPCServiceClient对象
serviceClient = new RPCServiceClient();
//获取Options对象
Options options = serviceClient.getOptions();
//指定调用webservice的URL
EndpointReference targetERP = new EndpointReference(wsdl);
options.setTo(targetERP);
//指定要调用的方法及wsdl文件的命名空间
QName opAddEntry = new QName("http://ws.apache.org/axis2",webServiceMethod);
//指定method的入参
Object[] opAddEntryArgs = inParam.values().toArray();
//指定方法返回值的数据类型class对象
Class[] classes = new Class[]{String.class};
//调用服务
responseStr = (String) serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0];
}catch(Exception e){
logger.error("RPCServiceClient error",e);
throw new RuntimeException("RPCServiceClient error",e);
}finally{
try {
serviceClient.cleanupTransport();
} catch (AxisFault e) {
logger.error("RPCServiceClient cleanupTransport error",e);
throw new RuntimeException("RPCServiceClient error",e);
}
}
return responseStr;
}
查找资料发现问题出在缺少必要的jar包上,经测试得知,使用RPCServiceClient所需的最少jar包如下:
axiom-api-1.2.13.jar错误二:
axiom-impl-1.2.13.jar
axis2-adb-1.6.2.jar
axis2-kernel-1.6.2.jar
axis2-transport-http-1.6.2.jar
axis2-transport-local-1.6.2.jar
commons-codec-1.3.jar
commons-httpclient-3.1.jar
commons-logging-1.1.1.jar
httpcore-4.0.jar
neethi-3.0.2.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.7.jar
原因:webservice调用连接池默认只有两个连接,每次调用完必须释放连接,否则很快就会没连接。需要在finally中加入以下代码,释放掉已有的连接。错误三:
finally{
try {
serviceClient.cleanupTransport();
} catch (AxisFault e) {
logger.error("RPCServiceClient cleanupTransport error",e);
throw new RuntimeException("RPCServiceClient error",e);
}
}
原因:缺少jar包 mail-1.4.jar
方法二:
/**
* 方法二: 应用document方式调用 webservice服务,用ducument方式可以摆脱我们不想要的耦合
* @param wsdl webservice地址
*
*/
public static void getRespByDocument(String wsdl,String user,String password) {
try {
//获取Options对象
Options options = new Options();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(wsdl);
options.setTo(targetEPR);
// options.setAction("urn:getPrice");
//获取ServiceClient对象
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
OMFactory fac = OMAbstractFactory.getOMFactory();
String tns = "http://quickstart.samples/";
// 命名空间,有时命名空间不增加没事,不过最好加上,因为有时会出问题
OMNamespace omNs = fac.createOMNamespace(tns, "");
OMElement method = fac.createOMElement("getPrice", omNs);
OMElement symbol = fac.createOMElement("symbol", omNs);
// symbol.setText("1");
symbol.addChild(fac.createOMText(symbol, "Axis2 Echo String "));
method.addChild(symbol);
method.build();
//为SOAP Header构造验证信息
addValidation(serviceClient,tns,user,password);
//调用服务
OMElement result = serviceClient.sendReceive(method);
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
/**
* 为SOAP Header构造验证信息,
* 如果你的服务端是没有验证的,那么你不用在Header中增加验证信息
*
* @param serviceClient
* @param tns 命名空间
* @param user
* @param passwrod
*/
public static void addValidation(ServiceClient serviceClient, String tns , String user, String passwrod) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(tns, "nsl");
OMElement header = fac.createOMElement("AuthenticationToken", omNs);
OMElement ome_user = fac.createOMElement("Username", omNs);
OMElement ome_pass = fac.createOMElement("Password", omNs);
ome_user.setText(user);
ome_pass.setText(passwrod);
header.addChild(ome_user);
header.addChild(ome_pass);
serviceClient.addHeader(header);
}