
@[toc]
前言
在webservice服务发布之后,通过soapUI工具测试成功之后。这个服务就可以在其他项目当中进行调用了。那么如何在只知道webservice的WSDL情况下进行调用呢?
项目中webservice服务的调用
目前在项目当中进行通信基本都是通过HTTP请求的方式,所以通过dk 自带wsimport.exe生成客户端代码的方法显得不是很实用。需要通过在项目当中进行编码的方式构建一个soap请求来调用webservice服务。只需要知道webservice服务的wsdl描述就可以了。
环境说明:
webservice服务是通过JDK自带的Endpoint发布的 (CXF框架的未进行测试)
JDK版本1.8
第一步 引入对应的jar
<dependency>
<groupId>com.predic8</groupId>
<artifactId>soa-model-core</artifactId>
<version>1.6.0</version>
</dependency>
第二步 通过wsdl获取发送soap请求的报文
通过浏览器查看WSDL描述

然后书写代码,方便理解。
@Test
public void test1() {
//通过wsdl解析器解析对应的webservice接口 获取到对应的wsdl xml描述对象
WSDLParser parser = new WSDLParser();
// 获取到的就是wsdl xml描述对象
Definitions parse = parser.parse("http://192.168.15.234:9090/webservice?wsdl");
System.out.println(parse.getAsString());
// 获取wsdl描述对象里面的portType 属性 这里的参数就是portType 的name
// 通常是webservice接口的实现类的名称
PortType portType = parse.getPortType("DemoWebServiceImpl");
// 根据name 获取到 portType 里面的 operation 属性
// 通常是webservice接口实现类里面的方法名称
Operation op = portType.getOperation("getName");
// 获取Bingding属性
Binding binding = parse.getBindings().get(0);
//通过SOARequestCreator 创建SOAP请求的XML报文模板
StringWriter writer = new StringWriter();
SOARequestCreator creator = new SOARequestCreator(parse,new RequestTemplateCreator(), new MarkupBuilder(writer));
creator.createRequest(portType.getName(), op.getName(), binding.getName());
//soap请求的xml报文模板
System.out.println(writer.toString());
}
最后获取到soap请求的xml报文模板如下:
<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<ns1:getName xmlns:ns1='http://demo/'>
<!-- optional -->
<arg0>?XXX?</arg0>
</ns1:getName>
</s11:Body>
</s11:Envelope>
第三步 通过httpClient发送soap请求
@Test
public void test1() {
//通过wsdl解析器解析对应的webservice接口 获取到对应的wsdl xml描述对象
WSDLParser parser = new WSDLParser();
// 获取到的就是wsdl xml描述对象
Definitions parse = parser.parse("http://192.168.15.234:9090/webservice?wsdl");
System.out.println(parse.getAsString());
// 获取wsdl描述对象里面的portType 属性 这里的参数就是portType 的name 通常是webservice接口的实现类的名称
PortType portType = parse.getPortType("DemoWebServiceImpl");
// 根据name 获取到 portType 里面的 operation 属性 通常是webservice接口实现类里面的方法名称
Operation op = portType.getOperation("getName");
// 获取Bingding属性
Binding binding = parse.getBindings().get(0);
//通过SOARequestCreator 创建SOAP请求的XML报文模板
StringWriter writer = new StringWriter();
SOARequestCreator creator = new SOARequestCreator(parse,new RequestTemplateCreator(), new MarkupBuilder(writer));
creator.createRequest(portType.getName(), op.getName(), binding.getName());
//soap请求的xml报文模板
System.out.println(writer.toString());
//修改模板里面的参数信息,也就是<arg0>属性的数据
String soapXml = writer.toString().replace("?XXX?","张三");
// 创建httpclient
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建post请求, 设置请求地址,请求头等信息
HttpPost httpPost=new HttpPost("http://192.168.15.234:9090/webservice?wsdl");
// 设置请求和传输超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(10000).build();
httpPost.setConfig(requestConfig);
//设置请求头 和请求数据
httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
StringEntity data = new StringEntity(soapXml, Charset.forName("UTF-8"));
httpPost.setEntity(data);
try {
//执行这个请求
CloseableHttpResponse execute = httpClient.execute(httpPost);
// 获取到请求执行结果代码
int statusCode = execute.getStatusLine().getStatusCode();
System.out.println("请求执行结果:"+statusCode);
// 获取到请求执行返回数据
HttpEntity entity = execute.getEntity();
String s = EntityUtils.toString(entity, "UTF-8");
System.out.println("请求执行返回数据:"+s);
} catch (IOException e) {
e.printStackTrace();
}
}
备注:返回数据也是一个xml格式的数据。
总结
简单来说就是通过httpclient发送一个post请求,传递的是XML数据给webservice。比较麻烦是调用过程当中xml数据的封装和解析。