下面就是在Internet Exploerer里直接调用这两个Web Method所得到的
xml格式的结果:
表5. GetPersons()的
返回结果
<?
xml version="1.0" encoding="utf-8"?>
<ArrayOfPerson
xmlns:xsd="http://www.w3.org/2001/
xmlSchema"
xmlns:xsi="http://www.w3.org/2001/
xmlSchema-instance"
xmlns="http://tempuri.org/">
<Person>
<Name>Alice</Name>
<Gender>Female</Gender>
</Person>
<Person>
<Name>Bob</Name>
<Gender>Male</Gender>
</Person>
<Person>
<Name>Chris</Name>
<Gender>Female</Gender>
</Person>
<Person>
<Name>Dennis</Name>
<Gender>Male</Gender>
</Person>
</ArrayOfPerson>
表6. GetPersonTable()的
返回的String类型的值
<PersonTable> <Person>
<Name>Alice</Name>
<Gender>Female</Gender>
</Person> <Person>
<Name>Bob</Name>
<Gender>Male</Gender>
</Person> <Person>
<Name>Chris</Name>
<Gender>Female</Gender>
</Person> <Person>
<Name>Dennis</Name>
<Gender>Male</Gender>
</Person> <Person>
<Name>Eric</Name>
<Gender>Male</Gender>
</Person> </PersonTable>
到这里,
xml Web Service的创建就已经完成了。.NET中创建的
xml Web Services遵循的是统一的行业标准(SOAP、
xml等),因此无论使用.NET语言还是使用非.NET语言,都可以调用它。尤其对于GetPersonTable()
返回的结果来说,只要用
xml Parser作简单的处理,就能把数据提取出来。下面就将演示如何在
Java中完成这一处理。
3. 在Java中调用.NET Web Services,处理返回的数据集合 编写客户端调用Web Services时,最快速简便做法的是利用工具根据Web Services的WSDL描述生成客户端代理类(Proxy),而不是直接对SOAP Toolkit进行编程。在.NET Framework中,这个工作可以由wsdl.exe完成。在Java中,可以在JBuilder或者VisualAge Java等Java IDE中安装一个叫做WASP Developer的免费插件,这个插件也能完成由WSDL描述生成Proxy类的工作。另外,该公司还提供了WASP Server for Java和WASP UDDI,降低了用户用Java开发Web Services以及建立UDDI服务的难度。
在本文的例子中,用了JBuilder 7+WASP Developer来调用前文中建立的.NET
xml Web Services。在调用之前,首先是用WASP Developer生成Proxy类。从图表7、8中可以看到,生成Proxy的工具已经在Java中也创建了一个Person类:
表7. 用WASP Developer生成的Proxy类

表8. WASP Developer创建的Person类
package javaclient.service1Soap12Clientstruct;
public class Person {
public java.lang.String Name;
public java.lang.String Gender;
}
/*
* Generated by WSDLCompiler, (c) 2002, Systinet Corp.
* http://www.systinet.com
*/
表9. 在Java中调用GetPersons()的代码
在Proxy类的基础上,就可以访问.NET编写的Web Services并提取数据了。对于GetPersons()来说,由于已经生成了Person类,所以调用代码非常简单直接:
import org.idoox.webservice.client.WebServiceLookup;
import org.idoox.wasp.Context;
import javax.swing.*;
import javax.swing.table.*;
try{
System.setProperty( "wasp.location","C:HomeUtilwasp_4.0SP2");
javaclient.service1Soap12Client.Service1Soap service;
String serviceURI = "http://localhost/dotNetHost/Service1.asmx";
String wsdlURI = "http://localhost/dotNetHost/Service1.asmx?wsdl";
WebServiceLookup lookup = (WebServiceLookup) Context.getInstance(Context.WEBSERVICE_LOOKUP);
service = (javaclient.service1Soap12Client.Service1Soap) lookup.lookup(
wsdlURI,
javaclient.service1Soap12Client.Service1Soap.class,
serviceURI);
Person[] persons=
service.GetPersons(new javaclient.service1Soap12Clientstruct.GetPersons()).GetPersonsResult;
DefaultTableModel model=new DefaultTableModel(new String[],0);
for(int i=0;i<persons.length;i++){
model.addRow(new String[]);
}
this.jTable1.setModel(model);
}
catch(Exception ex)
调用GetPersonTable()并解析
xml字符串要相对复杂一些,需要用到
xml Parser从图表6中的
xml字符串中提取数据,并逐一显示在JTable中。下面是从访问Web Method到解析
xml,最后提取数据并显示的完整代码,及其运行结果截图:
import javax.swing.*;
import javax.swing.table.*;
import org.idoox.webservice.client.WebServiceLookup;
import org.idoox.wasp.Context;
import org.w3c.dom.*;
import org.apache.
xml.serialize.*;
import org.apache.xerces.dom.*;
try{
System.setProperty( "wasp.location","C:HomeUtilwasp_4.0SP2");
javaclient.service1Soap12Client.Service1Soap service;
String serviceURI = "http://localhost/dotNetHost/Service1.asmx";
String wsdlURI = "http://localhost/dotNetHost/Service1.asmx?wsdl";
WebServiceLookup lookup = (WebServiceLookup) Context.getInstance(Context.WEBSERVICE_LOOKUP);
service = (javaclient.service1Soap12Client.Service1Soap) lookup.lookup(
wsdlURI,
javaclient.service1Soap12Client.Service1Soap.class,
serviceURI);
String result=
service.GetPersonTable(new javaclient.service1Soap12Clientstruct.GetPersonTable()).GetPersonTableResult;
DefaultTableModel model=new DefaultTableModel(new String[],0);
java.io.StringReader reader=new java.io.StringReader(result);
org.apache.xerces.parsers.DOMParser parser=new org.apache.xerces.parsers.DOMParser();
parser.parse(new org.
xml.sax.InputSource(reader));
org.w3c.dom.Document document=parser.getDocument();
org.w3c.dom.NodeList children=document.getDocumentElement().getChildNodes();
for(int i=0;i<children.getLength();i++){
org.w3c.dom.Node node=children.item(i);
if(node.getNodeName().equals("Person")){
org.w3c.dom.NodeList personAttrNodes=node.getChildNodes();
String name="N/A";
String gender="N/A";
for(int j=0;j<personAttrNodes.getLength();j++){
org.w3c.dom.Node attrNode=personAttrNodes.item(j);
String attrNodeName=attrNode.getNodeName();
if(attrNodeName.equals("Name"))else if(attrNodeName.equals("Gender"))else
}
model.addRow(new String[]);
}
}
this.jTable1.setModel(model);
}
catch(Exception ex)
4. 小结 从前面的叙述和代码中可以看出,对于"如何在Java/Delphi中使用.NET的Web Service
返回的DataSet"的问题,虽然在非.NET语言环境中直接接受DataSet类型的
返回值比较困难,但可以有其他的解决方案。
对于第一种解决方案,也就是采用自定义数据类型,它的优点是客户端代码非常简单,容易编写,而且容易理解。它的缺点是
服务器端需要定义新的类,而且当通过ADO.NET从数据库中提取数据以后,还要再手工编写代码,将DataSet中的数据遍历一遍,转存成自定义类型的对象。
对于第二种解决方案,就是用DataSet.Write
xml()的方案,它的优点和缺点正好和第一种方案是互补的。它在客户端需要编写较多的代码,尤其是需要用
xml Parser编程,提高了编程的难度。另一方面,它在
服务器端比较简单。