84457417 2010-12-16
作为客户端调用webservice通用的做法,通常利用axis或cxf生成客户端代码,如果调用的服少还能应付,如果调用服务比较多,生成的代码很多,很难管理,自己以前就是这样干。想到过wsdl解析生成soap报文,再通过httpclient发送请求,由于各种服务类型和服务样式,兼容性很难处理,没有去实施。
最近接触soapui和camel时间比较多,从这两个工具中找到我想要的代码和思路。能够解决各种服务类型和服务样式兼容性问题......直接通过一个实例来演示怎么调用,效果更比较清楚些。
实例描述:创建一个用户,返回值和参数都市javabeanUser.(其它参数类型如此)
解析的SOAP报文如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:demo="http://demo.cxf.starit.com/"> <soapenv:Header/> <soapenv:Body> <demo:createUser> <!--Optional:--> <arg0> <!--Optional:--> <address>?</address> <!--Optional:--> <name>?</name> </arg0> </demo:createUser> </soapenv:Body> </soapenv:Envelope>
需要的参数为:
Map<String, Object> params = new HashMap<String, Object>(); params.put("createUser.arg0.address", "Anhui Hefei"); params.put("createUser.arg0.name", "melin"); params.put("dumpSOAP", "");
map的key值为body下面的xpath路径。这种方式,主要是为了解决复杂参数的传值。
dumpSOAP是为了打印出soap报文替换参数前后的内容。
替换参数后的soap报文
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:demo="http://demo.cxf.starit.com/"> <soapenv:Header/> <soapenv:Body> <demo:createUser> <!--Optional:--> <arg0> <!--Optional:--> <address>Anhui Hefei</address> <!--Optional:--> <name>melin</name> </arg0> </demo:createUser> </soapenv:Body> </soapenv:Envelope>
调用返回一个map
Map<String, String> result = client.sendRequest("createUser", params, wsdlUrl);
返回内容
{createUserResponse.return.address=Anhui Hefei, createUserResponse.return.name=melin}
//----------------------------完整代码-----------------------------
public static void main(String[] args) throws Exception { String wsdlUrl = "http://localhost:9000/helloWorld?wsdl"; SoapClient client = new SoapClient(); Map<String, Object> params = new HashMap<String, Object>(); params.put("createUser.arg0.address", "Anhui Hefei"); params.put("createUser.arg0.name", "melin"); params.put("dumpSOAP", ""); Map<String, String> result = client.sendRequest("createUser", params, wsdlUrl); System.out.println(result); }
整个测试工程:https://j2eedev.googlecode.com/svn/trunk/SOAPUtil