1. 概述
很多正在開發或者打算開發XML Web Services的程式員都問過這樣的一個問題:"我的Web Service返回的結果是一個DataSet類型的對象,但如果我的用戶端不是用.NET寫的(因而沒有內建的DataSet類型),
那該如何調用這個Web Service並訪問DataSet中的資料呢?"。
對於這個問題,首先應該說的是:1)在多種語言共存的編程環境下,是不適合使用類似DataSet這種只屬於特定語言的資料類型的。不管是在XML Web Services還是CORBA的環境中,都應該盡量使用單一資料型別以及單一資料型別的數組。2)應當很謹慎的決定是否需要通過Web Service來返回大量資料。由於網路傳輸的開銷既包括HTTP串連建立的時間,也包括傳送資料的時間,因此需要在減少訪問伺服器次數和減少網路傳輸量之間尋找一個合適的平衡。如非必須,則不適合通過Web Service傳送含有幾十條或者幾百條資料的資料表。
然後,就問題本身而言,.NET Web Services返回的DataSet類型是可以直接被其他非.NET的用戶端解析的,因為即便是DataSet類型的傳回值,也會被表達成XML格式再進行傳輸。下面的例子就是一個傳回型別為DataSet的Web Method,及其被調用後返回的XML格式資料:
2. 建立.NET Web Services,返回資料集合
[WebMethod]
public DataSet GetPersonTable(string str)
...{
DataTable table = new DataTable("Person");
table.Columns.Add("Name");
table.Columns.Add("Gender");
table.Rows.Add(new string[2] ...{ "Alice", "Female" });
table.Rows.Add(new string[2] ...{ "Bob", "Male" });
table.Rows.Add(new string[2] ...{ "Chris", "Female" });
table.Rows.Add(new string[2] ...{ "Dennis", "Male" });
table.Rows.Add(new string[2] ...{ "Eric", "Male" });
DataSet dataset = new DataSet("PersonTable");
dataset.Tables.Add(table);
return dataset;
}
3. 在Java中調用.NET Web Services,處理返回的資料集合
try ...{
String wsdlUrl = "http://localhost/WebSite1/Service.asmx?op=GetPersonTable";
String soapActionURI = "http://tempuri.org/GetPersonTable";
Service service = new Service();
Call call = (Call) service.createCall();
//
call.setOperationName(new QName("http://tempuri.org/","GetPersonTable"));
call.setTargetEndpointAddress(new java.net.URL(wsdlUrl));
call.addParameter("a", org.apache.axis.encoding.XMLType.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_SCHEMA);
call.setUseSOAPAction(true);
call.setSOAPActionURI(soapActionURI);
Object[] objs = new Object[]...{"ssss"};
Object res = call.invoke( objs );
System.out.println(res);
Schema schema = (Schema)res;
DefaultTableModel model=new DefaultTableModel(new String[]...{"name","gender"},0);
schema.get_any()[1].getChildNodes().getLength();
int nLength=schema.get_any()[1].getChildNodes().item(0).getChildNodes().getLength();
String name="N/A";
String gender="N/A";
for(int i=0;i<nLength;i++)
...{
if(schema.get_any()[1].getChildNodes().item(0).getChildNodes().item(i).getChildNodes().item(0).getNodeName().equals("Name"))
...{
name=schema.get_any()[1].getChildNodes().item(0).getChildNodes().item(i).getChildNodes().item(0).getFirstChild().getNodeValue();
}
if(schema.get_any()[1].getChildNodes().item(0).getChildNodes().item(i).getChildNodes().item(1).getNodeName().equals("Gender"))
...{
gender=schema.get_any()[1].getChildNodes().item(0).getChildNodes().item(i).getChildNodes().item(1).getFirstChild().getNodeValue();
}
model.addRow(new String[]...{name,gender});
this.jScrollPane1.getViewport().add(jTable1, null);
}
jTable1.setModel(model);
}
catch (Exception ex)
...{
System.err.println(ex.toString());
}
4. 小結
從前面的敘述和代碼中可以看出,對於"如何在Java/Delphi中使用.NET的Web Service返回的DataSet"的問題,雖然在非.NET語言環境中直接接受DataSet類型的傳回值比較困難,但可以有其他的解決方案。