@[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 数据的封装和解析。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于