在過去的數年中,許多開發人員都使用了各種版本的J2EE,使服務器端軟件編程的情形得到了很大的改觀,現在,他們將再次挑戰SOAP,在服務器端軟件編程方面取得更大的進展。
SOAP服務的支持者認為:
·企業級應用服務器是服務(或事務)的集合。
·可以使用的服務應當很方便地列出來供用戶瀏覽、搜索和訪問。
·象現在的基于組件的開發模式那樣,將應用服務器設計為服務的集合將鼓勵開發人員采用更好的設計模式。
·這些事務能夠被重新定位、負載平衡、替代等。
而對SOAP持懷疑態度的人認為,SOAP是推廣CORBA和COM的又一次嘗試。他們指出,要簡單地訪問一個對象,需要完成太多的準備性工作,而且,UDDI帶來的好處也被夸大了。
那么,到底哪一種觀點更合理呢?對于一些思想開放的人士而言,在決定是否采用SOAP服務前,他們一定希望了解其中的一些核心技術。
解密UDDI
我們首先來看看UDDI代表什么?UDDI是Universal Description, Discovery and Integration(統一描述、發現和集成)的縮寫。UDDI的意圖是作為一個注冊簿,就象黃頁是一個地區企業的注冊簿一樣。象在黃頁中那樣,在UDDI注冊簿中,企業將在不同的目錄下注冊它們自己或其服務。通過瀏覽一個UDDI注冊簿,開發人員能夠查找一種服務或一個公司,并發現如何調用該服務。
除了黃頁外,UDDI還使用了白頁和綠頁。白頁是企業實體列表,綠頁是調用一項服務所必需的文檔。
UDDI的定義非常全面,足以適應不同種類的服務。一個UDDI服務定義可能代表一個傳真服務或電話服務。作為一種注冊簿,UDDI一般使用數據庫一類的軟件來實現,在該數據庫中,存在一個允許發布或查詢服務的有關信息。
UDDI數據模型
UDDI數據模型包括下面的主要元素:
·businessEntity:表示一個實際的企業。
·businessService:表示一個企業提供的服務。
·bindingTemplate:如何調用服務的說明。
·tModel>: Good luck understanding this! (Just kidding, I will explain this later.)
為了加深對UDDI數據模型的理解,我們來看看這些數據元素的UML表示法。圖1是這四種主要元素之間的關系圖:

從上面的圖中我們可以知道,一個businessEntity(一家公司)有一個能夠告訴我們更多有關公司信息的描述性URL和聯系人清單,此外,businessEntity還有一個商業服務清單。每種服務可能有多種調用方法,每種調用都由一個綁定模板描述。綁定模板詳細地描述了如何訪問一個服務,它受益于一系列描述用戶如何訪問這一服務的文檔。綁定模板和其必要的文檔之間的聯系是通過所謂的tModel完成的。在上面的圖中,這種聯系被簡單地描述為一個綁定模板有許多tModels。在進一步地解釋tModels與綁定模板的關系前,我們必須先弄清楚tModels是什么。
TModel是什么?
我們可以把tModel想象成數據庫庫中的一個獨立的表,其中包含下面的字段:名字、描述、URL、唯一的關健字。實際上,tModel就是包括有名字和描述,那么使用數據庫表表示它是否是一種浪費呢?我們下面就會討論這一問題:
下面是一個假想的tModel數據庫表中的二個實體:
鍵 名字 描述 URL
1 Java-class 表示一個具備完全資格的java類的名字 http://www.javasoft.com/
2 Jndi-home 表示一個JNDI名字 http://www.javasoft.com/
在將tModel比作數據庫表方面,有幾點值得注意。首先,tModel是一個獨立的表,意味著它可以不依賴其他軟件而存在;其次,tModel是查找表,提供了鍵與鍵的表示之間的轉換關系。從這一點來看,tModel象詞典那樣,是一個引用表。在一些數據庫中,這樣的表也被稱作是碼集。
因此,如果在上面的tModel中存在下面的記錄:
com.mycompany.HelloWorld, 1
com.mycompany.HelloWorldHome, 2
就意味著字符串com.mycompany.HelloWorld是一個有完整資格的Java類;而字符串com.mycompany.HelloWorldHome是一個JNDI名。
因此在一定程度上,tModels中唯一的鍵與“名字空間”這個概念差不多。為了進一步地說明這個問題,我們來看一下下面的數字:
904-555-1212
904-555-1213
1-56592-391-x
你能夠分清這些數字的意義嗎?我們需要在一個環境或名字空間中來確認,904-555-1212是電話號碼,904-555-1213是傳真號,1-56592-391-x是一個ISBN號。
因此在tModel數據庫表中,我們將需要定義三個實體:一個是電話號碼;一個是傳真號碼,一個是ISBN號碼。
下面我們以mycompany公司公布了一條號碼為1-800-my-helpline的電話支持熱線,并在UDDI中注冊。那么,我們的數據模型為:
company name: mycompany
Service name: helpline
tModel: key=11 (representing telephoneline), name=telephone,
description=telephone stuff, url:
some at&t url
binding:
accesspoint: 1-800-my-helpline
tModelInstanceInfo: 11
有了對tModel的基本理解后,我們就可以利用UML圖表來研究綁定模板與tModels之間的關系了。我在上面曾經說過,這將使我們對綁定模板如何完成UDDI的“如何調用一項服務”的要求有一個直觀的理解。

在圖2中,我們討論了一個綁定模板與tModels之間的關系。從圖表中我們可以看出,一個綁定模板可以指向一個由一個tModel確定的技術規格,技術規格有二部分組成:
·規格的類型。(例如電子郵件、傳真、WSDL、SOAP等。)
·確定輸入和輸出的文檔(在SOAP服務中,這些文檔可以是XML輸入/輸出消息格式。)
既然我們已經對tModels有了一定程度的詳細了解,就該再討論UDDI中更復雜的東西了,也就是身份包和類別包。
理解標識符包和類別包
如果說從概念上理解tModels是理解UDDI需要跨越的第一道障礙,那么理解標識符包和類別包則是需要跨越的第二道障礙。下面的例子可以幫助我們理解這二個概念。
例如,您的公司在美國開展業務需要有一個稅號,如果還在另外的國家(例如墨西哥)開展業務,就需要有一個墨西哥的稅號。為了能夠在UDDI注冊簿中獲取您的公司的這些信息,在UDDI中應當包括下面的內容:
公司名字:mycompany
標識符:
美國稅號:111111
墨西哥稅號:2223344
其他國家稅號: 333333
...其他的xml內容
<identifierBag>
<keyedReference tModelKey="US-tax-code"
keyName="taxnumber" keyValue="1111111">
<keyedReference tModelKey="Mexico-tax-code"
keyName="taxnumber" keyValue="2223344">
<keyedReference tModelKey="other-stuff"
keyName="taxnumber" keyValue="333333">
</identifiedBag>
... 其他的xml內容
現在明白tModels如何被用作名字空間了吧。為了進一步地深化對標識符包的理解,我們在下面的圖中再次解釋了標識符和類別包的概念:

從上面的圖中我們能夠看出,標識符包是一個在特定環境中的鍵/值對集合,這個環境從本質上說就是能夠唯一地解析名字/值對兒的名字空間,它是由tModel確定的。類別包也是如此,二者之間唯一的區別就是類別包中由tModel確定的名字空間是一個預先確定好的類別。
類別包
我想將公司歸類于飯店,其地理位置位于杰克遜維爾。
公司名字:mycompany
適用類:
企業類型:飯店
所在城市:杰克遜維爾
<categoryBag>
<keyedReference tModelKey="BusinessTypeClassification"
keyName="restaurant" keyValue="..">
<keyedReference tModelKey="CityClassification"
keyName="JAX" keyValue="..">
</categoryBag>
現在,我們已經搞清楚了tModels是如何用在標識符和類別包中的。從本質上說,tModels就是名字空間。
tModels也能被分類嗎?
我們已經明白了企業實體是如何利用使用了類別包的。另外,UDDI也允許tModels本身被分類。
我們用分層次的文件系統進行說明。目錄是用來對文件進行分類的,但目錄還可以在父目錄下再被分類。象硬盤上的目錄那樣,tModels也可以被分層次地進行組織。
下面我們來討論名字為getUniversalTime()的服務,該服務將返回當前全球任一地方的時間。二家存在競爭關系的公司可能會提供這一服務的不同實現。商業服務只限于在公司內部使用,公司之外的用戶是不可使用的:
company1:getTime()
company1:getCurrentTime()
這二者的作用相同,為了表明它們實現的是同一個被稱作getUniversalTime()的服務,我們可以定義如下所示的tModel:
tModel
name:: Get Universal Time
category: uddi-org:types, wsdl
[意味著這是一個由WSDL文檔定義的服務]
上面的定義表明getUniversalTime()是一個WSDL服務,可以由任何公司實現。
既然已經闡明了tModels和包之間的關系,我們下面可以看看一個tModel的UML表示:

從上面的圖表中,我們可以看出tModel基本上就是一個名字和描述,另外,它也可以包含一個URL,以提供更進一步的詳細資料。它可以由一個標識符包確定和由一個類別包進行分類。
我們已經知道,一個tModel所屬于的類別是由UDDI━━WSDL、SOAP等預先定義好的,下面是一個uddi-org:types名字空間中預先定義類別的清單:
tModel
identifier (唯一標識符)
namespace
categorization
specification
xmlSpec
soapSpec
wsdlSpec
protocol
transport
signatureComponent
如何開始在UDDI中創建一個服務?
在開始定義服務的tModel時,要求我們為服務指定一個名字和上面所列出的服務類型中的一個。當然了,如果不喜歡上面的分類可以自己創建類別。
我們可以針對上面定義的tModel開發一個商業服務。在商業服務定義中,我們需要指定一個指向定義了服務的輸入/輸出的WSDL文檔的URL。
在UDDI中為什么需要tModels?
在UDDI中使用tModels的目的如下:
·對商業實體進行標識和分類
·對商業服務進行標識和分類
·對tModels進行標識和分類
·將商業服務綁定到它們抽象的tModel定義上
UDDI名詞的快速參考
在看有關UDDI的資料時,如果看到很深奧的術語是一件很煩人的事兒,下面我們就把一些經常用到的與UDDI有關的概念搜集起來,通過比較幫助我們對UDDI概念的理解:
接口和實現
服務綁定是一個容器,接口依賴于其實現;綁定元素詳細說明了tModelInstaceInfo和instanceDetail, 我們將再通過一個例子加深對這一問題的例子。對于“獲得統一時間”服務而言,細節將提供定義了輸入、輸出的實際的WSDL文檔,綁定的訪問點將提供實現服務的物理機器和端口。了解了這些,我們可以得出如下的結論:
·為一種服務定義的tModel是允許多家公司提供該服務的多個實現的界面。
·服務綁定是具體的實現。
名字空間
Java、C++和XML中都有名字空間的概念,盡管其叫法可能不同,但它們都提供了使名字有意義的環境。在UDDI中,tModel象征著“名字”。當把這個名字作為目錄使用時,你的本意是,“我屬于這個名字”。從這個意義上說,tModel表示的是名字空間。
技術指紋
當一種服務被注冊為tModel時,我們可以注冊用來與該服務通訊的協議(例如WSDL、SOAP等)。因此根據所使用的協議不同,tModel有WSDL指紋或SOAP指紋。因此tModel被認為是技術性指紋,每種指紋與一種特定的協議有關。如果說一種tModel可以代表一個“技術性指紋”,我們也可以說tModel能夠表示一種“協議”。
分類
分類與類別、名字空間類似,它提供了一種環境,只有在這種環境下,一些數字和名字才有意義。例如,
白頁
UDDI注冊簿中的企業實體列表和根據名字搜索企業的能力。
黃頁
黃頁將企業實體按企業類別或其他適用的類別分類。
綠頁(技術規格)
綠頁有助于我們理解服務的定義和訪問服務的要求,serviceBindings和tModels也有助于這一目標的實現。
JAXR
JAXR是在服務注冊中使用的一種Java XML API。我們以前曾經討論過,UDDI中的所有元素都用XML文檔進行描述。從某種意義上說,嘦我們能夠發送包含有服務描述的XML消息,UDDI注冊簿就能夠對它進行注冊或更新。下面我們討論在沒有工具的情況下如何完成這一任務:
1、編寫必要的服務描述XML文檔。
2、理解SOAP頭部,以便能夠將XML文件作為一個SOAP附件發送給UDDI注冊簿。
3、使用SOAP客戶端Java API完成第二步中的任務。
4、通過編程的方式處理SOAP消息。
5、根據UDDI服務的描述,構造消息完成該UDDI服務的任務。
6、對每個消息,完成第2、3步中的操作。
如果使用JAXR,我們可以更好地完成這一任務。因為JAXR允許我們在發送XML消息時無需考慮SOAP頭部,而且是一種嚴格的面向消息的協議。使用JAXR,上面的任務將簡化為:
1、編寫必要的服務描述XML文檔。
2、使用JAXM API發送和接收XML消息,JAXR隱藏了SOAP信息。
3、根據UDDI服務構建消息完成該UDDI服務。(例如,向UDDI注冊簿注冊UDDI服務包含有4次信息交換過程。)這意味著我們仍然需要與XML內容打交道。
使用這種方式,我們只需處理高層次的Java API即可,這些Java API能夠產生必需的消息并通過JAXR傳輸它們。需要指出的一點是,JAXR也用來完成該任務。
下面列出了JAXR的一些目標:
·支持業界標準的XML注冊功能
·支持成員機構和企業的注冊
·支持任意注冊內容的存儲和提交
·支持XML、非XML注冊內容的管理
·支持注冊內容間用戶定義的結合
·支持用戶定義的注冊內容的多級分類
·支持基于定義的分類計劃的注冊內容查詢
·支持基于復雜查詢的注冊內容查詢
·支持基于關健詞的注冊內容查詢
·支持Web服務的共享
·支持合作伙伴間商業過程的共享
·支持合作伙伴間計劃的共享
·支持合作伙伴間商業文檔的共享
·支持合作伙伴間貿易伙伴協議的談判
·支持計劃匯編
·支持異類分布注冊
·支持參與各方發布/訂閱XML消息
JAXR將不僅僅支持UDDI,還會支持其他的類似注冊服務標準(例如ebXML)。
原文地址:
http://www.wyt2008.com/Article/java/web/200603/Article_921.html