在上兩篇寫WebService的文章中:
1)使用XFire+Spring構(gòu)建Web Service(一)——helloWorld篇
2)使用XFire+Spring構(gòu)建Web Service(二)
講到了如何使用XFire+Spring構(gòu)建WebService,并生成了對應(yīng)的wsdl文件。針對這兩篇文章,收到很多留言和讀者來信,大部分都是針對拿到wsdl后,如何根據(jù)wsdl生成對應(yīng)的Java代碼,并進行測試。
基于在開發(fā)過程中,很多時候都是拿到另一方的wsdl,需要與該方進行聯(lián)調(diào)測試,所以在本文中,我大概的整理了一下,希望能幫讀者解決一些問題。
第一章. 準備wsdl
這陣子正好在寫幾個wsdl,就拿其中一個來做實例吧。
首先貼下接口協(xié)議文檔:
1.1 數(shù)據(jù)類型
AccessCodeContext的數(shù)據(jù)類型:
域名
|
類型
|
Is Null
|
說明
|
accessCode
|
Varchar(32)
|
N
|
接入號
|
vccId
|
Varchar(20)
|
Y
|
集團標識
|
routeStrategy
|
Integer 默認1
|
N
|
路由策略:
1.轉(zhuǎn)接分機/組;
2.由CTI指定路由。
|
telephoneNumber
|
Varchar(32)
|
Y
|
分機/分機組(當路由策略為1時,該項不能為空)
|
serviceId
|
Varchar(20)
|
Y
|
服務(wù)(當路由策略為2時,該項不能為空)
|
1.2查詢接入號碼總數(shù)接口
接口定義
接口名稱
|
查詢接入號碼總數(shù)接口
|
接口描述
|
查詢接入號碼總數(shù)
1)accessCodeContext中的routeStrategy為0時,不過濾該項.
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
getTotalItem
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù):
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCodeContext
|
接入號碼屬性(當該對象為null時,查詢所有的接入號碼信息,若某項為空時,該項不參與查詢)
|
AccessCodeContext
|
n
|
3) 返回參數(shù)
發(fā)生其他異常時,以ServiceException異常的方式拋出。
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
totalItem
|
總數(shù)
|
Integer
|
Y
|
1.3查詢接入號碼列表接口
1)接口定義
接口名稱
|
查詢接入號碼列表接口
|
接口描述
|
查詢接入號碼列表
1)accessCodeContext中的routeStrategy為0時,不過濾該項.
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
list
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù):
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
startItem
|
起始查詢行號
|
Varchar
|
Y
|
maxItem
|
最大查詢行數(shù)
|
Varchar
|
Y
|
accessCodeContext
|
接入號碼屬性(當該對象為null時,查詢所有的接入號碼信息,若某項為空時,該項不參與查詢)
|
AccessCodeContext
|
n
|
3) 返回參數(shù)
發(fā)生其他異常時,以ServiceException異常的方式拋出。
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCodeContextArray
|
接入號碼信息數(shù)組
|
AccessCodeContext[]
|
Y
|
1.4 查詢單個接入號碼接口
1)接口定義
接口名稱
|
查詢接入號碼接口
|
接口描述
|
查詢接入號碼信息
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
find
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù):
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCode
|
接入號碼
|
varchar(32)
|
n
|
3) 返回參數(shù)
若接入號碼信息不存在或發(fā)生其他異常時,以ServiceException異常的方式拋出。
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCodeContext
|
接入號碼屬性
|
AccessCodeContext
|
N
|
1.5 增加接入號碼接口
1) 接口定義
接口名稱
|
增加接入號碼接口
|
接口描述
|
增加接入號碼,
說明:
1) 接入號碼不能重復;
2) 集團信息必須存在。
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
save
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù):
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCodeContext
|
接入號碼信息
|
AccessCodeContext
|
n
|
3) 返回參數(shù)
失敗時以異常的方式拋出ServiceException。
1.6 修改接入號碼接口
1) 接口定義
接口名稱
|
修改接入號碼接口
|
接口描述
|
修改接入號碼。
說明:
1) 接入號碼必須存在;
2) 集團信息必須存在。
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
update
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù)
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCodeContext
|
接入號碼信息
|
AccessCodeContext
|
n
|
3) 返回參數(shù)
失敗時以異常的方式拋出ServiceException。
1.7 刪除接入號碼接口
1)接口定義
接口名稱
|
刪除接入號碼接口
|
接口描述
|
刪除接入號碼:
1)接入號碼必須存在。
|
接口協(xié)議
|
webservice方式,使用utf-8編碼
|
方法名
|
delete
|
鏈接地址
|
|
接口提供者
|
|
主要使用者
|
ap
|
wsdl文件
|
|
2) 輸入?yún)?shù):
名稱
|
說明
|
數(shù)據(jù)類型
|
is null
|
accessCode
|
接入號碼
|
Varchar(32)
|
n
|
3) 返回參數(shù)
失敗時以異常的方式拋出ServiceException。
第二章 實例wsdl
相關(guān)的wsdl有5個,其中兩個是各個接口共用的,定義了共用的異常和數(shù)據(jù)對象之類的東西。
1)acd_common_faults.wsdl:定義了共用的異常ServiceException。
內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 編輯使用 XMLSpy v2006 U (http://www.altova.com) 由 any (any) -->
<!-- 2009.10.29 -->
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:acd_common_faults_xsd="http://cintel.com/ws/acd/system/v1_0/common/model" targetNamespace="http://www.cintel.com.cn/ws/acd/system/v1_0/common/faults" name="common_faults">
<wsdl:types>
<xsd:schema elementFormDefault="qualified">
<xsd:import namespace="http://cintel.com/ws/acd/system/v1_0/common/model" schemaLocation="acd_common_types.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ServiceException">
<wsdl:part name="ServiceException" element="acd_common_faults_xsd:ServiceException"/>
</wsdl:message>
</wsdl:definitions>

2)acd_common_types.xsd:定義了共用的數(shù)據(jù)類型
3)acd_accessCode_types.xsd:定義了接入碼的數(shù)據(jù)對象
<?xml version="1.0" encoding="UTF-8"?>
<!-- 20090618 -->
<xsd:schema xmlns:acd_common_xsd="http://cintel.com/ws/acd/system/v1_0/common/model" xmlns:acd_accessCode_xsd="http://cintel.com/ws/acd/system/v1_0/accessCode/model" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://cintel.com/ws/acd/system/v1_0/accessCode/model">
<xsd:element name="AccessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
<xsd:complexType name="AccessCodeContext">
<xsd:sequence>
<xsd:element name="accessCode" type="xsd:string" nillable="false"/>
<xsd:element name="vccId" type="xsd:string" nillable="true"/>
<xsd:element name="routeStrategy" type="xsd:int" nillable="false"/>
<xsd:element name="telephoneNumber" type="xsd:string" nillable="true"/>
<xsd:element name="serviceId" type="xsd:int" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

4)acd_accessCode_service.wsdl:定義了接入碼管理的各個方法
<?xml version="1.0" encoding="UTF-8"?>
<!-- 2009-10-29 -->
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://cintel.com/ws/acd/system/v1_0/accessCode/service" xmlns:interface="http://cintel.com/ws/acd/system/v1_0/accessCode/interface" targetNamespace="http://cintel.com/ws/acd/system/v1_0/accessCode/service" name="acd_accessCode_service">
<wsdl:import namespace="http://cintel.com/ws/acd/system/v1_0/accessCode/interface" location="acd_accessCode_interface.wsdl"/>
<wsdl:binding name="AccessCodeBinding" type="interface:AccessCode">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getTotalItem">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="list">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="find">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="save">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="update">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="delete">
<soap:operation style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AcessCodeService">
<wsdl:port name="AccessCode" binding="tns:AccessCodeBinding">
<soap:address location="http://localhost:8686/AccessCodeService/services/AccessCode"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

5)acd_accessCode_interface.wsdl:接口定義
<?xml version="1.0" encoding="UTF-8"?>
<!--2009-10-29 -->
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:acd_accessCode="http://cintel.com/ws/acd/system/v1_0/accessCode/interface" xmlns:acd_common_xsd="http://cintel.com/ws/acd/system/v1_0/common/model" xmlns:acd_common_faults="http://www.cintel.com.cn/ws/acd/system/v1_0/common/faults" xmlns:acd_accessCode_xsd="http://cintel.com/ws/acd/system/v1_0/accessCode/model" xmlns:acd_accessCode_local_xsd="http://cintel.com/ws/acd/system/v1_0/accessCode/local" targetNamespace="http://cintel.com/ws/acd/system/v1_0/accessCode/interface" name="acd_AccessCode_interface">
<wsdl:import namespace="http://www.cintel.com.cn/ws/acd/system/v1_0/common/faults" location="acd_common_faults.wsdl"/>
<wsdl:types>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://cintel.com/ws/acd/system/v1_0/accessCode/local">
<xsd:import namespace="http://cintel.com/ws/acd/system/v1_0/accessCode/model" schemaLocation="acd_accessCode_types.xsd"/>
<xsd:import namespace="http://cintel.com/ws/acd/system/v1_0/common/model" schemaLocation="acd_common_types.xsd"/>
<xsd:element name="getTotalItem" type="acd_accessCode_local_xsd:getTotalItem"/>
<xsd:complexType name="getTotalItem">
<xsd:sequence>
<xsd:element name="accessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="getTotalItemResponse" type="acd_accessCode_local_xsd:getTotalItemResponse"/>
<xsd:complexType name="getTotalItemResponse">
<xsd:sequence>
<xsd:element name="totalItem" type="xsd:int" nillable="false"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="list" type="acd_accessCode_local_xsd:list"/>
<xsd:complexType name="list">
<xsd:sequence>
<xsd:element name="startItem" type="xsd:int" nillable="false"/>
<xsd:element name="maxItem" type="xsd:int" nillable="false"/>
<xsd:element name="accessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="listResponse" type="acd_accessCode_local_xsd:listResponse"/>
<xsd:complexType name="listResponse">
<xsd:sequence>
<xsd:element name="accessCodeContextArray" type="acd_accessCode_xsd:AccessCodeContext" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="find" type="acd_accessCode_local_xsd:find"/>
<xsd:complexType name="find">
<xsd:sequence>
<xsd:element name="accessCode" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="findResponse" type="acd_accessCode_local_xsd:findResponse"/>
<xsd:complexType name="findResponse">
<xsd:sequence>
<xsd:element name="accessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="save" type="acd_accessCode_local_xsd:save"/>
<xsd:complexType name="save">
<xsd:sequence>
<xsd:element name="accessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="saveResponse" type="acd_accessCode_local_xsd:saveResponse"/>
<xsd:complexType name="saveResponse">
<xsd:sequence>
<xsd:element name="result" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="update" type="acd_accessCode_local_xsd:update"/>
<xsd:complexType name="update">
<xsd:sequence>
<xsd:element name="accessCodeContext" type="acd_accessCode_xsd:AccessCodeContext"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="updateResponse" type="acd_accessCode_local_xsd:updateResponse"/>
<xsd:complexType name="updateResponse">
<xsd:sequence>
<xsd:element name="result" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="delete" type="acd_accessCode_local_xsd:delete"/>
<xsd:complexType name="delete">
<xsd:sequence>
<xsd:element name="accessCode" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="deleteResponse" type="acd_accessCode_local_xsd:deleteResponse"/>
<xsd:complexType name="deleteResponse">
<xsd:sequence>
<xsd:element name="result" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="AccessCode_getTotalItemMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:getTotalItem"/>
</wsdl:message>
<wsdl:message name="AccessCode_getTotalItemMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:getTotalItemResponse"/>
</wsdl:message>
<wsdl:message name="AccessCode_listMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:list"/>
</wsdl:message>
<wsdl:message name="AccessCode_listMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:listResponse"/>
</wsdl:message>
<wsdl:message name="AccessCode_findMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:find"/>
</wsdl:message>
<wsdl:message name="AccessCode_findMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:findResponse"/>
</wsdl:message>
<wsdl:message name="AccessCode_saveMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:save"/>
</wsdl:message>
<wsdl:message name="AccessCode_saveMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:saveResponse"/>
</wsdl:message>
<wsdl:message name="AccessCode_updateMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:update"/>
</wsdl:message>
<wsdl:message name="AccessCode_updateMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:updateResponse"/>
</wsdl:message>
<wsdl:message name="AccessCode_deleteMessageRequest">
<wsdl:part name="parameters" element="acd_accessCode_local_xsd:delete"/>
</wsdl:message>
<wsdl:message name="AccessCode_deleteMessageResponse">
<wsdl:part name="result" element="acd_accessCode_local_xsd:deleteResponse"/>
</wsdl:message>
<wsdl:portType name="AccessCode">
<wsdl:operation name="getTotalItem">
<wsdl:input message="acd_accessCode:AccessCode_getTotalItemMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_getTotalItemMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
<wsdl:operation name="list">
<wsdl:input message="acd_accessCode:AccessCode_listMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_listMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
<wsdl:operation name="find">
<wsdl:input message="acd_accessCode:AccessCode_findMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_findMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
<wsdl:operation name="save">
<wsdl:input message="acd_accessCode:AccessCode_saveMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_saveMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
<wsdl:operation name="update">
<wsdl:input message="acd_accessCode:AccessCode_updateMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_updateMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
<wsdl:operation name="delete">
<wsdl:input message="acd_accessCode:AccessCode_deleteMessageRequest"/>
<wsdl:output message="acd_accessCode:AccessCode_deleteMessageResponse"/>
<wsdl:fault name="ServiceException" message="acd_common_faults:ServiceException"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>

第三章 在MyEclispe中通過wsdl生成Java代碼
3.1 建立工程環(huán)境
在MyEclipse中建立一個工程,例如建立一個名為wsdl2java的WEB工程。需要添加到WEB-INF/lib目錄下的包如下所示:

將wsdl目錄拷貝到工程目錄,例如src/wsdl目錄下。
3. 2. 根據(jù)wsdl文件生成對應(yīng)的java類
選擇新建的工程后,點擊右鍵,選擇“Run As”->“Run”,如下圖所示:

彈出窗口如下圖所示:

在上圖中,左邊選擇“Java Application”后,點擊左上角的新增“”按鈕new configuration,頁面如下圖所示:

在上圖中,將“Include libraries when searching for a main class” 勾上,而后點擊“Main class”右邊的“Search”按鈕,彈出窗口如下圖所示:

在上圖中輸入WSDL2Java后,查找到axis這個jar包中對應(yīng)類,點擊“OK”按鈕,此時主窗口如下圖所示:

在上圖中點擊“Arguments”頁簽,Arguments里把要生成的web service URI或wsdl文件寫進去,最后點run。在下圖中輸入的是wsdl文件的路徑: src/wsdl/acd_accessCode_interface.wsdl、src/wsdl/acd_accessCode_service.wsdl:

生成的代碼的結(jié)構(gòu)如下圖所示:

第四章 更簡便的生成Java代碼的方法
本章講述的方法是筆者采用的方法,也是筆者所推薦的,原理與前一章相同,但是要簡便一些。
4.1 準備jar包
將上一章提到的6個jar包放到某個目錄,例如E:\amigo\project\ws_lib
4.2 拷貝wsdl以及相關(guān)文件
將上面章節(jié)5個wsdl文件拷貝到某個目錄,例如:E:\interface
4.3 編寫一個批處理文件
編寫一個根據(jù)wsdl生成Java代碼的批處理文件,以后都可以拿來用。在wsdl文件所在目錄創(chuàng)建批處理文件createPackageByWsdl.bat,編寫該文件內(nèi)容:
set LibPath=E:\amigo\project\ws_lib

set AxisClassPath=%LibPath%\axis.jar;%LibPath%\commons-logging.jar;%LibPath%\commons-discovery-0.2.jar;%LibPath%\jaxrpc.jar;%LibPath%\saaj.jar;%LibPath%\wsdl4j.jar;

set WSDL2JavaCommand=java -classpath %AxisClassPath% org.apache.axis.wsdl.WSDL2Java
set WsDeploy=-s


%WSDL2JavaCommand% %WsDeploy% acd_accessCode_interface.wsdl
%WSDL2JavaCommand% %WsDeploy% acd_accessCode_service.wsdl
在后面可加入更多的wsdl文件。
編寫完成后,運行該批處理文件,可在同目錄下生成指定的wsdl對應(yīng)的Java類。生成的文件與上一章的文件一樣。
注意:第一行指定的是jar所在的目錄,讀者需要進行修改。
posted on 2009-11-20 13:27
阿蜜果 閱讀(10889)
評論(6) 編輯 收藏 所屬分類:
Web Service