本篇将结合实例,一步步实现Java对第三方提供的web service地址的调用,实现数据(XML)返回,以及数据解析(重要),从而实现不同语种之间的数据通信。
Web Service 服务端(博主写的一个XXX体检预约服务,数据均来自于MS SQL数据库)
开发语言:Delphi
wsdl地址(本地):http://localhost:9090/wsdl/ISJSService
Service服务方法如下:
方法 PhysicalBySex:根据性别返回体检套餐
MS SQL中关于 性别 "男"(后面调用我们会用到这个)的体检套餐如下:
当然,上面只是为了铺垫说明,数据的源头哪来的,不然,下面讲调用的时候,都不知道调用的是哪个服务,至少没讲之前,我们知道,Web Service服务是由Delphi开发的,当然,这是一门古老的语言,但不可否认,这门语言很有魅力,开发桌面应用程序非常简单便捷,由于,太古老,用的人少,相关学习资料也少,所以现在,市场上,delphi程序员,基本上没剩多少了,好多都转Java了,伤心。
不管你服务是Delphi写的,还是C#或者其他语言写的,Web Service都是无关语言平台的,因此,只要你能提供Service的地址,我就可以拿到数据,当然,数据是由提供方约定的,必须按照对方的约定去调用Web Service中相关的Methods。
本篇,我讲利用Eclipse中自带的Web Services Project,来创建我们的Service Client,从而来消化一切可以访问的到的第三方Web Service 地址。
一、创建一个Dynamic Web Project ,名称叫"WebServiceCall"
二、右键项目"WebServiceCall",创建一个Web Service Client
将上述Service地址:http://localhost:9090/wsdl/ISJSService(你们的可能是一个外网地址,这里我只举例说明我自己电脑上部署的web Service服务),拷贝到Service definition一栏中,同时动一下竖行滚动条,至Deploy client:
然后直接Finish,我们会看到:
我们主要看两个地方:
A、接口ISJSService.java:
首先这个ISJSService,对应我们地址中的
其次接口中的方法physicalBySex对应第三方web service中的方法
B、实现类ISJSServiceProxy.java:
这个里面的代码就不贴了,下面我们看一下,如何进行测试。
测试前,交代下测试需要用到的jar包:
测试单元:junit-4.12.jar、hamcrest-all-1.3.jar
XML操作:dom4j-1.6.1.jar
日志单元:log4j-1.2.16.jar
src下面,新建一个测试包,并添加一个测试类:
我们写一个测试方法Test,测试一下服务是否可以调通:
ServiceTest.java:
package com.appleyk.test;
import java.rmi.RemoteException;
import org.junit.Test;
import org.tempuri.ISJSServiceProxy;
public class ServiceTest {
@Test
public void Test(){
//url:http://localhost:9090/wsdl/ISJSService
ISJSServiceProxy oj = new ISJSServiceProxy();
try {
String reString = oj.physicalBySex("男");
System.out.println(reString);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
我们 Run As JUnit Test后,输出信息如下:
ok,我们成功调用Delphi开发的Web Service服务中的physicalBySex方法,我们将XML串用工具XMLSpy打开如下:
现在,我们拿到了响应消息XML串(当然,第三方服务提供的返回数据也有可能是JSON串),关键一步就是解析XML节点,我们利用org.dom4j提供的Document类,来操作XML:
完整ServiceTest.java:
package com.appleyk.test;
import java.rmi.RemoteException;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.junit.Test;
import org.tempuri.ISJSServiceProxy;
public class ServiceTest {
@Test
public void Test(){
//url:http://localhost:9090/wsdl/ISJSService
ISJSServiceProxy oj = new ISJSServiceProxy();
try {
String reString = oj.physicalBySex("男");
System.out.println(reString);
try {
Document document = DocumentHelper.parseText(reString);
Element RNode = document.getRootElement();
System.out.println("根节点:"+RNode.getName());
int i = 0;//根节点下父节点个数
int j = 0;//父节点下面子节点个数
//迭代根节点下面的孩子节点
Iterator<Element> NodeList = RNode.elementIterator();
while(NodeList.hasNext()){
Element FNode = NodeList.next();
String NodeName = FNode.getName();
System.out.print("节点"+(i+1)+":"+NodeName);
if (NodeName=="Return"){
System.out.println("-->NodeValue = "+FNode.getStringValue());
}
if(NodeName=="ExamSuite"){//还需要迭代一次其子节点以及属性
System.out.println("");
//迭代ExamSuite节点下面的孩子节点
Iterator<Element> ChildNodeList = FNode.elementIterator();
while(ChildNodeList.hasNext()){
Element CNode = ChildNodeList.next(); //每次取出一个子节点
NodeName = CNode.getName();
System.out.print("子节点"+(j+1)+":"+NodeName+",id = "+CNode.attributeValue("id"));
System.out.print(",NodeValue = "+CNode.getData());
System.out.println("");
j++;
}
}
i++;
}
} catch (DocumentException e) {
e.printStackTrace();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
我们看下 最终解析结果:
对于org.dom4j提供的Document操作,我们还可以将主要方法封装成一个Helper类,因为上述我们的demo显得有些冗余,很多地方重复用到了节点迭代,本篇作为讲解,没有做到这一块,如果将重复的代码加以封装,上述的测试demo将会大大缩减,感兴趣的朋友,可以自行研究一下dom4j提供的方法。
其他第三方Web Service 均可以使用本篇所讲述的一样操作,前提是,服务地址有效!