摘要:
多编程语言之间互相调用的情况很常见,这里是一则Java调用C#程序编写的WebService示例.
环境:
JAVA: Eclipse Kepler Service Release 1
引用类库:Axis1.0、Log4J
以下为MetaInfo.
Class-Path:
lib/axis.jar
lib/jaxrpc.jar
lib/mail.jar
lib/saaj.jar
lib/wsdl4j-1.5.1.jar
lib/commons-discovery-0.2.jar
lib/commons-logging-1.0.4.jar
lib/dom4j-1.6.1.jar
lib/jaxen-1.1.1.jar
lib/log4j-1.2.13.jar
lib/slf4j-api-1.5.2.jar
lib/slf4j-nop-1.5.2.jar
关键点:
1.call.setOperationName必须做QName转化(命名空间NameSpace识别用);
2.call.addParameter一定不能用QName转化,如果做过转化,会导致WebService无法识别入口参数;
3.call.setUseSOAPAction(true);
call.setSOAPActionURI(wsdl_Qname + method);
详细说明:
通过WSDL文件,解读入口参数、返回类型等.
比如c#Webservice提供一个 UpdateCheckItemsState 过程,在wsdl中:
- <wsdl:message name="UpdateCheckItemsStateSoapIn">
<wsdl:part name="patient_id" type="s:string" />
</wsdl:message>
- <wsdl:message name="UpdateCheckItemsStateSoapOut">
<wsdl:part name="UpdateCheckItemsStateResult" type="s:boolean" />
</wsdl:message>
里面就是入口参数和返回结果,分别是String和Boolean型.
以下为示例代码:
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.log4j.Logger;
// 状态更新
private void UpdateCheckItemsState () {
// 读取wsdl
remoteUrl = "http://192.168.0.199/WsPacsTrans.asmx?wsdl";
if ((remoteUrl == null) || (remoteUrl.isEmpty())) {
System.out.println("remotewsdl为空");
return;
}
try {
Service myservice = new Service();
Call call = (Call) myservice .createCall();
call.setEncodingStyle(null);
call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR,
Boolean.FALSE);
call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS,
Boolean.FALSE);
call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
String wsdl_Qname = "";
String method = "UpdateCheckItemsState";
wsdl_Qname = "http://www.yourname.com/";//此处用wsdl实际的NameSpace名称
// setOperationName 必须做QName转化
call.setOperationName(new QName(wsdl_Qname, method));
// 入口参数- patient_id,此处不能做QName转化处理
call.addParameter("patient_id",
XMLType.XSD_STRING, ParameterMode.IN);
// 返回参数
call.setReturnType(XMLType.XSD_BOOLEAN);
call.setUseSOAPAction(true);
call.setSOAPActionURI(wsdl_Qname + method);
call.setTargetEndpointAddress(new URL(remoteUrl));
boolean result = (boolean) call.invoke(new Object[] { "12342234" });// 12342234 为测试值,实际运行时传递需要的值
log.info("状态更新结果:" + result);
} catch (Exception e) {
e.printStackTrace();
log.error("状态更新出错:" + e.toString());
}
}
后记:
1.注意类库的版本,如果出现莫名其妙的问题,首先要分析这个原因;
2.其它调试要点欢迎大家分享、补充。