監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價(jià)咨詢管理系統(tǒng) | 工程設(shè)計(jì)管理系統(tǒng) | 甲方項(xiàng)目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

Web服務(wù)的(革)創(chuàng)新,第4部分

申請(qǐng)免費(fèi)試用、咨詢電話:400-8352-114

AMTeam.org

Web服務(wù)的(革)創(chuàng)新,第4部分

--Web服務(wù)描述語(yǔ)言 (WSDL)


Graham Glass

CEO/首席設(shè)計(jì)師,The Mind Electric

2001 年 2 月

這篇文章描述的是 Web 服務(wù)描述語(yǔ)言 (WSDL),WSDL是采用 XML語(yǔ)言來(lái)描述 Web 服務(wù)的屬性,例如它做什么,它位于哪里和怎樣調(diào)用它。本文還介紹了 IBM 的 WSDL 工具包,此工具包能夠從 WSDL 中生成存根,并簡(jiǎn)化 Web 服務(wù)應(yīng)用的創(chuàng)建過(guò)程。

歡迎進(jìn)入本專欄的第 4 部分,本專欄重點(diǎn)講述 Web 服務(wù)技術(shù)正在革新和創(chuàng)新的方面。在第 3 部分(請(qǐng)參閱參考資料)中,我展示了簡(jiǎn)單對(duì)象存取協(xié)議 (SOAP) 如何在后臺(tái)工作。在這一部分中,我會(huì)解釋 WSDL,這個(gè)描述 Web 服務(wù)的核心屬性的標(biāo)準(zhǔn)方法,和一些能支持 WSDL 來(lái)加速開(kāi)發(fā)過(guò)程的工具。

工具和安裝

我們將在這個(gè)部分使用兩個(gè)新的工具:

IBM WSTK 2.1:IBM Web 服務(wù)工具包 2.1 (請(qǐng)參閱參考資料)包含 Apache SOAP、WSDL 生成器和通用描述、發(fā)現(xiàn)和集成 (UDDI) 客戶端。由于在這一系列中我們一直都在使用 Apache SOAP 2.0,所以我們繼續(xù)使用它作為我們的 SOAP 服務(wù)器,但是這一部分我們將使用 WSTK 的 WSDL 生成器。

IBM WSDL 1.1 工具包:IBM Web 服務(wù)描述語(yǔ)言工具包(請(qǐng)參閱參考資料)生成來(lái)自于 WSDL 的客戶端和服務(wù)器的存根。它的代碼被封裝為 wsdl.jar,它使用 WSTK 的 bsf.jar (Bean 腳本框架)和 xalan.jar (XML 樣式表單處理器)文件。

一旦您下載并安裝了這些工具,請(qǐng)確保 wsdl.jar、bsf.jar 和 xalan.jar 在您的類路徑 (CLASSPATH) 下,這樣您就可以準(zhǔn)備構(gòu)造你的第一個(gè)帶有 WSDL 的程序了。

介紹 WSDL

Web 服務(wù)的一個(gè)主要思想,就是未來(lái)的應(yīng)用將由一組應(yīng)用了網(wǎng)絡(luò)的服務(wù)組合而成。只要兩個(gè)等同的服務(wù)使用統(tǒng)一標(biāo)準(zhǔn)和中性的方法在網(wǎng)絡(luò)上宣傳自己,那么從理論上說(shuō),一個(gè)應(yīng)用程序就可以根據(jù)價(jià)格或者性能的標(biāo)準(zhǔn),從兩個(gè)彼此競(jìng)爭(zhēng)的服務(wù)之中選出一個(gè)。除此之外,一些服務(wù)允許在機(jī)器之間復(fù)制,因而可以通過(guò)把有用的服務(wù)復(fù)制到本地儲(chǔ)存庫(kù),來(lái)提高允許運(yùn)行在特定的計(jì)算機(jī)(群)上的應(yīng)用程序的性能。

如果您想一想,會(huì)發(fā)現(xiàn)這很類似于人力勞務(wù)市場(chǎng)的運(yùn)作。提供工作的網(wǎng)站和雇傭公司為工人和老板提供中介服務(wù),利用簡(jiǎn)歷和工作描述來(lái)加快匹配過(guò)程。如果找到了一個(gè)好的匹配,感興趣的雙方就會(huì)嘗試磋商可接受的條件。如果達(dá)成了協(xié)議,工人或者去老板那里開(kāi)工,或者利用因特網(wǎng)和遠(yuǎn)程通信來(lái)作為代替的工作途徑。

Web 服務(wù)描述語(yǔ)言是 XML 中相當(dāng)于簡(jiǎn)歷的等同物 -- 描述 Web 服務(wù)做什么,它在哪里及如何調(diào)用它。想知道它是什么樣的,先看看 Xmethods 網(wǎng)站上運(yùn)行的貨幣交換服務(wù)的 WSDL(請(qǐng)參閱參考資料)。如果訪問(wèn)過(guò) http://www.xmethods.net/sd_ibm/CurrencyExchangeService.wsdl,您會(huì)看到服務(wù)的頂級(jí)描述。單擊這個(gè) WSDL 的 URL 地址,您就會(huì)看到在清單 1 中的 WSDL 代碼。

請(qǐng)注意,如果訪問(wèn) XMethods 網(wǎng)站,對(duì)于每個(gè) WSDL,您會(huì)看到兩個(gè)版本,其中一個(gè)是特別用于 IBM WSDL。這是因?yàn)楫?dāng)前 IBM 的 WSDL 工具包中有一個(gè)錯(cuò)誤,就是不讓它處理來(lái)自于其他工具包的 WSDL。這個(gè)問(wèn)題不久就會(huì)被修復(fù);同時(shí),我使用 XMethods 為創(chuàng)建了一個(gè)特為本文服務(wù)的版本。

讓我們來(lái)查看一下 WSDL 文檔中的每一部分,從 段開(kāi)始。


元素包括一個(gè)或者多個(gè)服務(wù)的定義。大多數(shù)情況下,一個(gè) WSDL 文件定義一個(gè)單獨(dú)的服務(wù)。 標(biāo)記后通常緊跟著以下屬性的聲明:

name:這個(gè)屬性是可選的,用來(lái)說(shuō)明服務(wù)的主要目的。

targetNamespace:這個(gè)屬性定義了關(guān)于服務(wù)信息的邏輯命名空間,并且各服務(wù)的屬性值通常是不同的。這個(gè)屬性在稍后會(huì)作更進(jìn)一步的討論。

xmlns:tns:在許多的 WSDL 文件中,這個(gè)命名空間并不出現(xiàn)(包括我們的示例),但是很快就會(huì)流行起來(lái)的。如果出現(xiàn),則被設(shè)置成 targetNamespace 的值。這個(gè)屬性在稍后會(huì)作更進(jìn)一步的討論。

xmlns:soap 和 xmlns:xsd:它們是標(biāo)準(zhǔn)命名空間的定義,在以后的 WSDL 文檔中被用作指定特定的 SOAP 的信息和數(shù)據(jù)類型。

xmlns:缺省的 WSDL 文檔的命名空間,被設(shè)置到
http://schemas.xmlsoap.org/wsdl/ 。所有的 WSDL 標(biāo)記,像 、 都駐留在這個(gè)命名空間之內(nèi)。

之中,有三個(gè)概念性的部分:

: 服務(wù)提供什么操作。

: 操作怎樣被調(diào)用。

: 服務(wù)位于哪里。

除此之外,服務(wù)所使用的任何復(fù)雜數(shù)據(jù)類型必須在一個(gè)可選的 部分里面被定義,而 部分必須直接放在 部分之前。因?yàn)槲覀兊氖纠呛?jiǎn)單的而且只使用原始的參數(shù)類型,因而沒(méi)有 部分。

讓我們?cè)敿?xì)的看看每一個(gè)部分。



一個(gè) 對(duì)應(yīng)在調(diào)用者和服務(wù)之間傳遞的一條信息。一個(gè)規(guī)則的有往返的遠(yuǎn)程方法調(diào)用有兩條消息,一條負(fù)責(zé)請(qǐng)求,一條負(fù)責(zé)響應(yīng)。每一個(gè) 可以沒(méi)有任何部分,或者有多個(gè)部分,每個(gè)部分都有一個(gè)名字和可選的類型。當(dāng) WSDL 描述一個(gè)對(duì)象時(shí),每一個(gè)部分映射到一個(gè)方法調(diào)用的參數(shù)上。如果一個(gè)方法返回為 void,那么響應(yīng)就是一條空信息。

一個(gè) 對(duì)應(yīng)一套單個(gè)或多個(gè)操作,而一個(gè) 定義了一個(gè)特定的輸入/輸出消息序列。每一個(gè)輸入/輸出的消息屬性必須對(duì)應(yīng)前面定義過(guò)的 的名稱。如果一個(gè)操作只指定了輸入,則只是單向操作。輸出后面緊跟著輸入則是 請(qǐng)求-響應(yīng) (solicit-response) 操作,單一的輸入是一個(gè)通告。當(dāng) WSDL 描述一個(gè)對(duì)象時(shí),每一個(gè) 映射一個(gè)方法并且每一個(gè) 映射一個(gè) Java 接口或類。

在這個(gè)示例中,getRate 操作接受了一個(gè) getRateRequest 消息作為它的輸入,并返回一個(gè) getRateResponse 消息作為它的輸出。



對(duì)應(yīng)于用特定的協(xié)議 -- 如 SOAP 或者 CORBA -- 來(lái)實(shí)現(xiàn)的 。綁定的類型屬性必須對(duì)應(yīng)定義過(guò)的 的名稱。因?yàn)?WSDL 是中性的協(xié)議,所以您可以指定 SOAP、CORBA、DCOM 和其它的標(biāo)準(zhǔn)協(xié)議的綁定。如果一個(gè)服務(wù)支持不止一個(gè)協(xié)議,WSDL 應(yīng)該對(duì)每一個(gè)它支持的協(xié)議都包含一個(gè)

在示例中, 部分表明使用標(biāo)準(zhǔn)的 SOAP 編碼進(jìn)行的 RPC 到 HTTP 的通信。也請(qǐng)注意 soapAction (在最后的部分描述)在這個(gè)示例中的設(shè)置是設(shè)置成空串,并且服務(wù)的 URI 被設(shè)置成 "urn:xmethods-CurrencyExchange"。



一個(gè) 是一個(gè)端口集,而 代表了在特定端點(diǎn)進(jìn)行特定綁定的可用性。端口的綁定屬性必須對(duì)應(yīng)于前面定義過(guò)的 的名稱。

在示例中,通過(guò) Xmethods 網(wǎng)站的 CurrentExchangeBinding 綁定可訪問(wèn) 。



任何 WSDL 元素可以聲明一個(gè)可選的 元素,其中包含人們可讀的關(guān)于那個(gè)元素的信息。在示例中,唯一有文檔描述的元素是 。對(duì)于其他的元素,例如獨(dú)立操作,有文檔描述也是很普通的。

使用 WSDL 來(lái)生成客戶端存根

因?yàn)?WSDL 包含了對(duì)服務(wù)接口的完整描述,所以可以使用它來(lái)創(chuàng)建能簡(jiǎn)化服務(wù)訪問(wèn)的存根。

IBM WSDL 工具包允許您為 Apache SOAP 創(chuàng)建存根。為了說(shuō)明這個(gè)問(wèn)題,讓我們創(chuàng)建一個(gè)客戶端存根,它允許我們調(diào)用在 Xmethods 上建立的貨幣交換服務(wù)。首先,建立一個(gè) demo3 目錄來(lái)存放這部分的所有軟件。然后通過(guò)使用瀏覽器的 File, Save as 選項(xiàng),把示例CurrentExchange的 WSDL 文件保存到這個(gè)目錄下。

然后通過(guò)鍵入下面的命令來(lái)建立客戶端存根:

demo3> java com.ibm.wsdl.Main -in CurrencyExchangeService.wsdl

這產(chǎn)生了一個(gè)叫做 CurrencyExchangePortTypeProxy.java 的客戶端存根類(如清單 2 所示)。如果得到了 "unable to load JDK compiler" 的消息,您可以忽略掉,因?yàn)槲覀儗⑹謩?dòng)編譯客戶端存根了。

就象您能看到的,客戶端的存根看上去就像我們?cè)谇懊娌糠掷锸褂眠^(guò)的代碼??蛻舳顺绦颥F(xiàn)在能夠像常規(guī)的 Java 對(duì)象那樣,使用代理服務(wù)類來(lái)訪問(wèn) Web 服務(wù)(請(qǐng)參閱清單 3)。

清單 3:一個(gè)代理服務(wù)的客戶端類

public class Client1
{
public static void main( String[] args ) throws Exception
{
CurrencyExchangePortTypeProxy exchange = new CurrencyExchangePortTypeProxy();
float rate = exchange.getRate( "USA", "japan" );
System.out.println( "rate = " + rate );
}
}

如果您編譯并運(yùn)行這些文件,您應(yīng)該能夠看到在圖 1 里的輸出。

圖 1:來(lái)自于 CurrencyExchangePortTypeProxy.java 的輸出


生成 WSDL

大多數(shù)廠商的工具包包括某些從一個(gè)組件中自動(dòng)生成 WSDL 的方法,其中包括 IBM WSTK 和 Microsoft .NET studio。為了說(shuō)明 WSTK 如何允許從一個(gè)服務(wù)生成 WSDL,我將使用在清單 4 中的天氣服務(wù)。

清單 4:從一個(gè)組件中生成 WSDL

public class Weather
{
public float getTemp( String zipcode )
{
System.out.println( "getTemp( " + zipcode + " )" );
return 56;
}

public void setTemp( String zipcode, float temp )
{
System.out.println( "setTemp( " + zipcode + ", " + temp + " )" );
}
}

為了給這個(gè)類創(chuàng)建 WSDL,首先要編譯它,然后在 demo3 目錄里啟動(dòng) WSTK 的 serviceWizard。在嘗試調(diào)用下面這條命令之前,要確保 wstk-2.1bin 在您的PATH路徑設(shè)置之中:

demo3> serviceWizard

您應(yīng)該看到如圖 2 中的輸出窗口。

圖 2:Web 服務(wù)生成工具


單擊 Next,就會(huì)提示您輸入類的名字和它的類路徑。對(duì)于這個(gè)示例,其它的地方設(shè)置成默認(rèn)值就可以了。圖 3 顯示了您如何填寫各個(gè)字段。

圖 3:Web 服務(wù)生成工具中的 WSDL 信息


當(dāng)您單擊 Next,會(huì)要求您選擇希望通過(guò) WSDL 來(lái)暴露什么方法。如圖 4 所示,按住 Shift 鍵選擇所有的方法。

圖 4:通過(guò) WSDL 取出的所選方法


最后,您得到了一個(gè)摘要(在圖 5 中),并且要按 Finish 來(lái)結(jié)束這個(gè)過(guò)程。

圖 5: Web 服務(wù)創(chuàng)建工具摘要


恭喜您,您已經(jīng)創(chuàng)建了您的第一個(gè) WSDL 文件!事實(shí)上,您實(shí)際創(chuàng)建了兩個(gè)文件:

Weather_Service-interface.wsdl:這個(gè)文件包括一個(gè) WSDL 描述的 、 部分,它描述了 Web 服務(wù)的接口(請(qǐng)參閱清單 5)。

Weather_Service-impl.wsdl:這個(gè)文件定義了 WSDL 描述的 部分,然后導(dǎo)入 Weather_Service-interface.wsdl(請(qǐng)參閱清單 6)。

這是很好的一個(gè)拆分,因?yàn)樗鼫p少了實(shí)現(xiàn)規(guī)范中的接口規(guī)范部分的重復(fù)。從理論上來(lái)說(shuō),您可以有很多的 *impl.wsdl 文件對(duì)應(yīng)一個(gè) *interface.wsdl 文件,并且搜索像 UDDI(下一個(gè)部分將會(huì)討論)這樣的注冊(cè)表,來(lái)尋找與一個(gè)特定接口描述對(duì)應(yīng)的一個(gè)或多個(gè)實(shí)現(xiàn)。

一個(gè)有趣的問(wèn)題是: 部分真的是屬于 WSDL 接口文件?還是屬于實(shí)現(xiàn)文件?您可以認(rèn)為它是屬于實(shí)現(xiàn)文件,因?yàn)樗菍iT用于特別的綁定,例如 SOAP 或 CORBA。我們只好等著看是否會(huì)有一個(gè)未來(lái)的標(biāo)準(zhǔn)來(lái)為此設(shè)定規(guī)范。

清單 5:Weather_Service-interface.wsdl


targetNamespace="
http://www.weatherservice.com/Weather-interface"
xmlns="
http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="
http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="
http://www.weatherservice.com/Weather"
xmlns:xsd="
http://www.w3.org/1999/XMLSchema">
name="IngetTempRequest">
type="xsd:string"/>

name="OutgetTempResponse">
type="xsd:float"/>

name="InsetTempRequest">
type="xsd:string"/>
type="xsd:float"/>

name="Weather_Service">

message="IngetTempRequest"/>
message="OutgetTempResponse"/>

name="setTemp">
message="InsetTempRequest"/>


name="Weather_ServiceBinding"
type="Weather_Service">
transport="
http://schemas.xmlsoap.org/soap/http"/>
name="getTemp">
soapAction="urn:weather-service"/>

encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:weather-service"
use="encoded"/>


encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:weather-service"
use="encoded"/>


name="setTemp">
soapAction="urn:weather-service"/>

encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:weather-service" use="encoded"/>



清單 6:Weather_Service-impl.wsdl


targetNamespace="
http://www.weatherservice.com/Weather"
xmlns="
http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="
http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="
http://www.weatherservice.com/Weather"
xmlns:xsd="
http://www.w3.org/1999/XMLSchema">
name="Weather_Service">
IBM WSTK 2.0 generated service definition file
binding="Weather_ServiceBinding"
name="Weather_ServicePort">
location="
http://localhost:8080/soap/servlet/rpcrouter/"/>
< BR> location="
http://localhost:8080/wsdl/Weather_Service-interface.wsdl"
namespace="
http://www.weatherservice.com/Weather-interface">

從 WSTK WSDL 文件中生成存根

從 WSTK WSDL 文件來(lái)創(chuàng)建存根顯得有一點(diǎn)復(fù)雜,由于 Weather_Service.impl 之中的導(dǎo)入說(shuō)明,使得 WSDL 存根產(chǎn)生器需到接口文件的位置執(zhí)行HTTP Get。在這個(gè)示例中,它是
http://localhost:8080/wsdl/Weather_Service-interface.wsdl。確保 Tomcat 能夠?yàn)檫@個(gè)文件提供服務(wù),在 Tomcat 的根文件夾 $TOMCAT_HOMEwebappsROOT 中創(chuàng)建一個(gè)目錄 wsdl,并把所有的 .wsdl 文件復(fù)制到這個(gè)目錄中。然后,假定 tomcat 正運(yùn)行在 demo3 目錄下,在 demo3 目錄下鍵入以下命令:

demo3> java com.ibm.wsdl.Main -in Weather_Service-impl.wsdl

Tomcat 將會(huì)從自己的 wsdl 目錄下提供 Weather_Service-interface.wsdl 文件,而您應(yīng)該會(huì)在 demo3 目錄下得到一個(gè)名叫 Weather_ServiceProxy.java 的存根類。清單 7 是一個(gè)測(cè)試客戶端程序,它可以訪問(wèn)在您本地的 Tomcat 服務(wù)器上運(yùn)行的天氣服務(wù):

清單 7:天氣 Web 服務(wù)的測(cè)試代碼

public class Client2
{
public static void main( String[] args ) throws Exception
{
Weather_ServiceProxy weather = new Weather_ServiceProxy();
float temp = weather.getTemp( "75248" );
System.out.println( "temp = " + temp );
weather.setTemp( "75248", 84 );
}
}

想要運(yùn)行這個(gè)程序,編譯 demo3 目錄下的所有 Java 文件,然后使用 Apache 配置屏,用 URN urn:weather-service 來(lái)部署天氣服務(wù),然后執(zhí)行客戶端程序。圖 6 顯示了當(dāng)您填完所有的字段后,配置屏看上去的樣子:

圖 6:運(yùn)行 Web 服務(wù)


當(dāng)您運(yùn)行程序時(shí),客戶端應(yīng)該顯示 getTemp() 的調(diào)用返回,而 Tomcat 窗口將會(huì)顯示出收到的 setTemp() 調(diào)用。

目標(biāo)命名空間

由于 WSDL 文件能夠?qū)肫渌?WSDL 文件,因此總有可能發(fā)生名字沖突的時(shí)候。所以,最晚拿到的 WSDL 文件需要在它們的 部分里面定義 targetNamespace 和 xml:tns 的屬性,在那里 targetNamespace 被設(shè)成對(duì)應(yīng)于特定的 WSDL(通常是原始的 WSDL 文件的名稱)的一個(gè)唯一 URL。完成此功能的 WSDL 生成器利用 tns: 對(duì)部分與部分之間的引用做范圍界定,來(lái)防止相同名字沖突。舉一個(gè)示例,在清單 8 里,操作聲明使用 tns: 前綴,明確地把它使用的消息的范圍界定在一個(gè)特定的 WSDL 文件中。






很可能所有的 WSDL 工具包很快都會(huì)采用這種方法。

下一部分

在下一部分中,我們會(huì)了解 Web 服務(wù)怎樣使用 UDDI (通用描述,發(fā)現(xiàn)和集成)來(lái)宣傳自己,以便讓別的 Web 服務(wù)使用。我們將用新發(fā)布的 IBM UDDI4J 工具包在 UDDI 庫(kù)里發(fā)布和綁定 Web 服務(wù)。

參考資料

  • 在第 1 部分中,Graham 詳細(xì)介紹了構(gòu)建 Web 服務(wù)應(yīng)用以實(shí)現(xiàn)對(duì)等分布式網(wǎng)絡(luò)的優(yōu)勢(shì)及其面臨的挑戰(zhàn)。
  • 在第 2 部分中,Graham 提供了如何開(kāi)發(fā) Web 服務(wù)的循序漸進(jìn)的解釋,其中包括您需要什么工具,如何安裝它們,如何編寫代碼以及如何配置服務(wù)。
  • 在這個(gè)專欄的第 3 部分中,Graham 詳細(xì)介紹了 SOAP 在線上交換信息的行為并解釋了它是怎樣工作的。
  • 請(qǐng)回顧第一個(gè)版本的 WSDL 1.0 規(guī)范。
  • 請(qǐng)從 alphaWorks 下載 IBM 的 WSDL 工具包。
  • 請(qǐng)從 alphaWorks 下載 IBM 的 Web 服務(wù)工具包。
  • Xmethods.net 有一個(gè)提供公共的 Web 服務(wù)的目錄,這篇文章用到了其中的一個(gè)服務(wù)。

關(guān)于作者
Graham Glass (graham-glass@mindspring.com) 是 The Mind Electric 的創(chuàng)始人、CEO 和首席設(shè)計(jì)師。該公司設(shè)計(jì)、構(gòu)建和頒發(fā)許可證給前瞻性的分步式計(jì)算基礎(chǔ)設(shè)施。他相信,因特網(wǎng)的演變將反映出生物思維的演變,而協(xié)助人們和企業(yè)有效聯(lián)網(wǎng)的體系結(jié)構(gòu)能幫助人們理解將人腦聯(lián)結(jié)在一起的體系結(jié)構(gòu)。

在創(chuàng)建 The Mind Electric 之前,Graham 是 ObjectSpace 的主席、CTO 和聯(lián)合發(fā)起人之一。該公司總部位于達(dá)拉斯,專門從事商家到商家的集成。Graham 還是 ObjectLesson(一家提供前沿技術(shù)培訓(xùn)的公司)的創(chuàng)辦人。他為 Prentice Hall 撰寫了兩本有關(guān) UNIX 和 STL 的書籍,并以他對(duì)新興技術(shù)的熱情和清晰闡述而成為受歡迎的演說(shuō)家??赏ㄟ^(guò) graham-glass@mindspring.com 和他聯(lián)系。

瀏覽:Web服務(wù)的(革)創(chuàng)新,第1部分

Web服務(wù)的(革)創(chuàng)新,第2部分

Web服務(wù)的(革)創(chuàng)新,第3部分

發(fā)布:2007-03-25 13:26    編輯:泛普軟件 · xiaona    [打印此頁(yè)]    [關(guān)閉]
相關(guān)文章:
石家莊OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號(hào)1層9號(hào)

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費(fèi)獲取試用系統(tǒng)

QQ在線咨詢