14.1 Web Services和面向服務的軟件架構(Service Oriented Architecture,簡稱SOA)概述:
在最新Java開發世界里,我們經常會遇到這樣一個名詞:Web Services(Web服務)。同時還會發現,與這個名詞同時出現的多是各大主流技術供應商,各大技術供應商無一不在關注這一領域的發展。從Microsoft的.NET架構,到SUN的SUN ONE,以及IBM的Web Services,都體現了這些重量級的技術提供者對Web Services的推崇與重視。
電子商務的發展促進了Web Services的發展。Web服務可以使公司降低進行電子商務的成本,更快地部署解決方案以及開拓更多的新機遇。Web服務使應用程序的集成比以前更快、更容易而且更便宜。它更注重服務語義而不那么注重網絡協議語義的消息,從而實現了業務功能的松散耦合。這些特性對于在企業之間和企業內部通過web連接業務功能是非常理想的。它提供了一致化(Uniform)的編程模型,從而在企業內外都可以利用通用的基礎設施并以一種通用的方法進行應用程序集成。
要理解Web Services, 首先需要認識面向服務的軟件架構(Service Oriented Architecture,簡稱SOA),Web Services是SOA架構系統的一個實例。
14.1.1面向服務的軟件架構(SOA)
1. 面向服務中的基本概念
在面向服務的架構中包含一些基本的概念,透過這些基本概念可以進一步了解面向服務的架構。
(1) 服務的概念
在SOA中的服務是指能夠處理一些任務過程的動作的抽象概念,這些服務可以被描述,可以被發現,可以由服務代理負責向請求者提供服務并給出結果。代理是指請求或者提供服務的人所使用的軟件工具,人通過代理進行交互操作。
(2) 消息的概念
服務代理之間需要通過消息的傳遞進行交互操作,消息的內容含有一定的語義和數據,消息傳輸需要與某個通信協議相綁定才能夠實現。
(3) 服務的描述和發現
眾多的服務組成一個開放系統,除了需要提供信息交互方式以外,還需要提供相互了解的機制,這就需要提供描述和發現的方式。代理可以通過服務的描述來了解一個服務的內容,包括使用這個服務的技術信息、訪問這個服務的地址信息等內容。當新的服務被投入到系統之中后,它需要被注冊,并且要能夠被發現,使它可以被利用起來。
2.為什么需要面向服務的軟件
由于軟件需求的擴大,軟件系統變得越來越復雜。面對復雜的系統資源,我們需要一種更加合理的方式將不同類型、不同位置的子系統有力地結合起來,這種整合并不是將它們之間綁定得更加緊密,而是利用更加松散的方式來建立這個系統。
SOA通過松散的方式將分布式的軟件模塊結合起來,與舊有系統集成相比有著明顯的優勢。對于服務的使用者來說,可以簡單地通過服務的描述來獲取服務,系統各部分之間不必為了某一部分的升級而改變,在服務的過程中不同的軟件模塊可以充當不同的角色,從而構成整個系統的工作體系。
在SOA當中,一個服務代表的是一個由服務提供者向服務請求者發布的一些處理過程,這個過程在被調用之后,獲得服務請求者所需要的一個結果。在這個過程中,服務請求者可以向任何能夠提供此項服務的服務提供者來請求服務,服務實現的過程對于服務請求者來說是透明的。
隨著系統分布式和多種結構復合程度的提高,SOA的巨大優勢將進一步被挖掘。
(1) 建立松散耦合的系統
松散耦合系統的優點已經被業內充分地認可,SOA作為一種分布式的系統,它實現了一種服務和描述等概念相結合的架構。
SOA中的服務在SOA架構中被標準的描述語言所描述,并通過與某種傳輸協議的綁定來實現相互之間的交互。這種基于服務的架構使整個系統成為一個松散耦合的結構,利用與通信協議的綁定將分布式系統中的所有部分連接起來,利用語義和服務的描述,在代理之間進行交互。
(2) 提高軟件的重用性
面向服務的架構還提高了對軟件的重用性。與組件方式相比,SOA系統中的單個服務的改變不會對其他部分造成嚴重的影響,同時利用服務的描述使同一服務可以充分地被其他系統所調用,各個系統之間形成了高度的重用性。
現在正在被廣泛使用的一些服務,正在不斷地被各個系統所重用,重用的條件十分簡單,只要了解服務的描述,或者可以訪問到服務的描述地址即可。與組件重用相比,服務的重用還具有與實現語言無關的特點,重用服務的客戶端程序不需要使用與服務實現部分同樣的開發語言,一切交互的過程都是利用與實現無關的方式進行的。
(3) 提供按需服務的代碼
面向服務的架構也使得系統的實現虛擬化,在SOA架構中的請求和提供之間交互或相互代理的過程中,可計算的代碼資源分布在松散結構中的各個部分上,當請求發生時才被調用和服務,所有計算過程都是按照請求者的需求進行的。服務的對象分為有狀態和無狀態兩種方式提供服務,按照需求提供服務,也可以利用緩沖機制優化系統的系統。
總之,SOA使代碼的開發變得更有服務的目的性,使開發更加有效和合理。
14.1.2 SOA與 Web 2.0
另外,我們補充一下SOA與目前同樣熱門的Web 2.0的關系。
實際上Web 2.0 和SOA的概念在很大程度上是相同的,只是被粉飾成為軟件的不同部分(如果的確存在不同的話),也就是說SOA和Web 2.0有很多重疊的東西,例如都是基于調用(invoke)的服務,都能存在于網絡的任何位置等等。
SOA和Web 2.0的共性遠大于它們之間的區別,而且Web 2.0在推廣SOA方面起到了一定作用。到現在為止,SOA和Web 2.0擁有不同的支持者- SOA更多涉及企業結構和商務開拓,而Web 2.0更關注用戶。這種差別隨著更多企業接納Web 2.0而在變化,但是這兩項技術有著不同的重心: Web 2.0告訴我們數據是軟件應用中最重要的部分,而SOA告訴我們服務才是中心。SOA中傳輸數據的服務也非常重要,但是傳統SOA更關注IT系統的接合處而不是那些能使接合處更具價值的東西。也就是說,SOA也許是通暢的管道,但并不是系統中通過的水的價值。許多行業領導者說企業同時需要SOA類方法的結構和Web 2.0方法的創業能力。
SOA和Web 2.0之間有許多共有的要素:
l 軟件重組
l 管理
l 軟件就是服務
l 應用就是平臺
l 無意識的使用
l 開放
l AJAX
l 互操作性
l 貨幣化
l 安全
l 網絡導向架構
特別要說的是,最后一條網絡導向架構或者Web Oriented Architecture(WOA)是關鍵的內容,最終有可能會將SOA和Web 2.0合為一體。
了解了SOA后, 我們來介紹什么是Web Services。Web Services是SOA架構系統的一個實例。從技術角度來講,Web Services是一種新的技術架構、新的軟件應用環境。它的系統架構和實現技術完全繼承已有的技術,可以認為Web Services是Internet的一種延伸,是現有的Internet面向更好的互操作能力的一個延伸。
14.2. Web Services的概念
Web Services,從字面上理解就是通過Web提供的服務。我們可以理解Web Services是自包含的、模塊化的應用程序,它可以在網絡(通常為Web)中被描述、發布、查找以及調用;也可以理解Web Services是基于網絡的、分布式的模塊化組件,它執行特定的任務,遵守具體的技術規范,這些規范使得Web Sevices能與其他兼容的組件進行互操作;也可以這樣理解,所謂Web服務,它是指由企業發布的完成其特別商務需求的在線應用服務,其他公司或應用軟件能夠通過Internet來訪問并使用這項應用服務
對于Web Services,很多人會與Web Service混為一談,認為二者指的是同一個事物。其實不然,前者指的是用于建構Web Service的技術框架,后者指的是使用Web Services技術而創建的應用實例。Web Services是描述了一些操作的接口,基于標準化的XML消息傳輸機制,我們可以通過網絡訪問這些操作。Web Services使用規范的、基于XML的WSDL(Web Services Description Language)語言描述的,這稱為Web Services的服務描述。這一描述囊括了與服務交互所需要的全部細節,包括消息格式(詳細描述操作的輸入輸出消息格式)、傳輸協議和位置。該接口隱藏了服務實現的細節,允許通過獨立與服務實現、獨立于軟硬件平臺、獨立于編寫服務所用的編程語言的方式使用該服務。這使得基于Web Services的應用程序具有松散耦合、面向組件和跨技術實現的特點。Web Services都履行一定的特定業務或任務,可以實現同其他Web Services一起用于實現復雜的商業交易。
從外部使用者角度而言,Web Services是一種部署在Web上的對象和組件,具備以下特征:
.完好的封裝性:
Web服務既然是一種部署在web上的對象,自然具備對象的良好封裝性,對于使用者而言,他能且僅能看到該對象提供的功能列表。
.松散耦合
這一特征也是源于對象/組件技術,當一個Web服務的實現發生變更的時候,調用者是不會感到這一點的,對于調用者來說,只要Web服務的調用界面不變,Web服務實現的任何變更對他們來說都是透明的,甚至是當Web服務的實現平臺從J2EE遷移到了.NET或者是相反的遷移流程,用戶都可以對此一無所知。對于松散耦合而言,尤其是在Internet環境下的Web服務而言,需要有一種適合Internet環境的消息交換協議,而XML/SOAP正是目前最為適合的消息交換協議。
.使用協議的規范性
這一特征從對象而來,但相比一般對象,它更加規范化和易于理解。首先,作為Web服務,對象界面所提供的功能應當使用標準的描述語言來描述(比如WSDL);其次,由標準描述語言描述的服務界面應當是能夠被發現的,因此這一描述文檔需要被存儲在私有的或公共的注冊庫里面。同時,使用標準描述語言描述的使用協約將不僅僅是服務界面,它將被延伸到Web服務的聚合、跨Web服務的事務、工作流等,而這些又都需要服務質量(QoS)的保障。其次,我們知道安全機制對于松散耦合的對象環境的重要性,因此我們需要對諸如授權認證、數據完整性(比如簽名機制)、消息源認證以及事務的不可否認性等運用規范的方法來描述、傳輸和交換。最后,在所有層次的處理都應當是可管理的,因此需要對管理協約運用同樣的機制。
.高度可集成能力
由于Web服務采取簡單的、易理解的標準,Web協議作為組件界面描述和協同描述規范,完全屏蔽了不同軟件平臺的差異,無論是CORBA、DCOM還是EJB,都可以通過這一種標準的協議進行互操作,實現了在當前環境下最高的可集成性。
14.2.1 Web Services的核心技術
Web Services 是一種基于組件的軟件平臺,是面向服務的Internet 應用。Web Services 是應用于Internet 的,而不是限于局域網或試驗環境,這就要求Web Services 框架必須適用于現有的Internet 軟件和硬件環境,即服務的提供者所提供的服務必須具有跨平臺、跨語言的特性。其次,Web Services 所提供的服務不但是面向人,而且需服務于其它應用系統。現有的Web網站也可以認為是面向服務的,但這種服務僅僅可以提供給人使用(只有人類才可以讀懂瀏覽器下載的頁面) 。而新一代的Web Services 所提供的服務應能被機器所讀懂,例如其它應用程序及移動設備中的軟件系統。這樣,我們可以看出,Web Services 的發展方向實際上是構造一個基于現有Internet 技術之上的分布計算系統。
Web Services 框架的核心技術包括SOAP(Simple Object Access Protocol,簡單對象訪問協議) ,WSDL(Web Services Description Lanuage,Web服務描述語言) 和UDDI(Universal Description,Discovery and Integration,通用描述,發現,集成) ,它們都是以標準的XML 文檔的形式表述的。
XML是Web Services技術體系中最基礎的標準,Web Services的一切都建立在XML技術的基礎之上,包括Web Services的消息、描述和服務實現的各個環節。利用XML,Web Services的服務提供者和請求者可以利用不同的開發語言來協作完成服務調用的過程。XML是Web Services技術體系中的很多標準得以建立的基礎,在Web Services系統中無處不在。
SOAP 是Web services 的通信協議。SOAP是一種簡單的、輕量級的基于XML 的機制,用于在網絡應用程序之間進行結構化數據交換。SOAP包括三部分:一個定義描述消息內容的框架的信封,一組表示應用程序定義的數據類型實例的編碼規則,以及表示遠程過程調用和響應的約定。
WSDL表示WEB服務說明語言。WSDL文件是一個XML 文檔,用于說明一組SOAP消息以及如何交換這些消息,通過WSDL可以描述一個服務的信息。這些信息使不了解這個服務的開發者可以建立調用這個服務的客戶端代碼,或者通過WSDL幫助生成實現它的基本代碼結構。WSDL在Web Services的實際開發過程中起著重要的作用。
Web Services是基于互聯網的應用程序模塊,用于在互聯網上運行,它采用開放的UDDI(Universal Description,Discovery and Integration,通用描述,發現,集成)標準。UDDI標準先由IBM、微軟、Ariba制訂,到目前為止獲得了130多家公司的支持。UDDI 提供一種發布和查找服務描述的方法。UDDI 數據實體提供對定義業務和服務信息的支持。WSDL 中定義的服務描述信息是UDDI注冊中心信息的補充。UDDI提供了一個開放,平臺獨立的技術框架,來使企業之間能在互聯網上找到對方的服務,定義它們在互聯網上的交互活動,以及這些信息的共享方式。
Web 服務體系結構基于三種角色(服務提供者、服務注冊中心和服務請求者)之間的交互。
服務提供者。從企業的角度看,這是服務的所有者。從體系結構的角度看,這是托管訪問服務的平臺。
服務請求者(用戶)。從企業的角度看,這是要求滿足特定功能的企業。從體系結構的角度看,這是尋找并調用服務,或啟動與服務的交互的應用程序。服務請求者角色可以由瀏覽器來擔當,由人或無用戶界面的程序(例如,另外一個 Web 服務)來控制它。
服務注冊中心。這是可搜索的服務描述注冊中心,服務提供者在此發布他們的服務描述。在靜態綁定開發或動態綁定執行期間,服務請求者查找服務并獲得服務的綁定信息(在服務描述中)。對于靜態綁定的服務請求者,服務注冊中心是體系結構中的可選角色,因為服務提供者可以把描述直接發送給服務請求者。同樣,服務請求者可以從服務注冊中心以外的其它來源得到服務描述,例如本地文件、FTP 站點、Web 站點、廣告和服務發現(Advertisement and Discovery of Services,ADS)或發現 Web 服務(Discovery of Web Services,DISCO)。
Web Services 的體系架構如圖1 所示

Web Services 服務提供方通過WSDL(Web Services Description Language) 描述所提供的服務,并將這一描述告知Web Services 注冊服務器。注冊服務器依據WSDL 的描述,依照UDDI (Universal Description Discovery and Integration) 的協定更新服務目錄并在Internet 上發布。用戶在使用Web Services 前先向注冊服務器發出請求,獲得Web Services 提供者的地址和服務接口信息,之后使用SOAP 協議(Simple Object Access Protocol) 與Web Services 提供者建立連接,進行通信。Web Services 的技術主要建立在XML 的規范之上,這保證了這一體系結構的平臺無關性、語言無關性和人機交互性能。
14.2.2 Web 服務開發生命周期
Web 服務開發生命周期包括了設計和部署以及在運行時對服務注冊中心、服務提供者和服務請求者每一個角色的要求。每個角色對開發生命周期的每一元素都有特定要求。
Web 服務開發生命周期有以下四個階段:
1. 構建
生命周期的構建階段包括開發和測試 Web 服務實現、定義服務接口描述和定義服務實現描述。我們可以通過創建新的 Web 服務、把現有的應用程序變成 Web 服務和由其它 Web 服務和應用程序組成新的 Web 服務來提供 Web 服務的實現。
2. 部署
部署階段包括向服務請求者或服務注冊中心發布服務接口和服務實現的定義,以及把 Web 服務的可執行文件部署到執行環境(典型情況下,Web 應用程序服務器)中。
3. 運行
在運行階段,可以調用 Web 服務。在此,Web 服務完成部署,成為可操作的服務。服務請求者可以進行查找和綁定操作。
4. 管理
管理階段包括持續的管理和經營 Web 服務應用程序。安全性、可用性、性能、服務質量和業務流程問題都必須被解決。
接下來我們具體展開Web Services原理。
14.3.Web Services原理
首先,我們將看看 Web 服務的一個概念性協議棧以及這個協議棧的細節。然后我們將討論選擇網絡協議的標準。我們還將回顧一下基本的基于 XML 的消息傳遞分布式計算。我們將用服務描述擴展基本的 XML 消息傳遞,而服務描述是根據它的協議棧來解釋的。接下來,我們將討論服務描述在 Web 服務體系結構中的角色,說明支持靜態和動態 Web 服務應用程序的服務發布技術的范圍。我們還將圍繞服務發布討論服務發現的角色。最后,我們將描述基本 Web 服務體系結構的擴展,電子商務需要這些擴展才能使用 Web 服務。
14.3.1 Web 服務協議棧
要以一種可交互操作的方式執行發布、發現和綁定這三個操作,必須有一個包含每一層標準的 Web 服務協議棧。圖 2 展示了一個概念性 Web 服務協議棧。上面的幾層建立在下面幾層提供的功能之上。垂直的條表示在協議棧中每一層必須滿足的需求。
圖2. Web 服務概念性協議棧

Web 服務協議棧的基礎是網絡層。Web 服務要被服務請求者調用,就必須是可以通過網絡訪問的。互聯網上可以公用的 Web 服務使用普遍適用的網絡協議。HTTP 憑借其普遍性,成為了互聯網可用的 Web 服務真正的標準網絡協議。Web 服務還可以支持其它互聯網協議,包括 SMTP 和 FTP。內部網域可以使用可靠消息傳遞和調用基礎結構,如 MQSeries 和 CORBA 等等。
下一層是基于 XML 的消息傳遞,它表示使用 XML 作為消息傳遞協議的基礎。選擇 SOAP 作為 XML 消息傳遞協議有很多原因:
它是使用 XML 傳送以文檔為中心的消息以及遠程過程調用的標準化封裝機制。
SOAP 很簡單;它基本上是一個用 XML 信封作為有效負載的 HTTP POST。
SOAP 比對 XML 簡單的 HTTP POST 更受青睞,因為它定義了一個標準機制,這個機制將正交擴展(orthogonal extension)合并為使用 SOAP 報頭和對操作或函數進行標準編碼的消息。
SOAP 消息支持 Web 服務體系結構中的發布、查找和綁定操作。
服務描述層實際上是描述文檔的一個協議棧。首先,WSDL 是基于 XML 的服務描述的真正標準。這是支持可交互操作的 Web 服務所需的最小標準服務描述。WSDL 定義了服務交互的接口和結構。要指定業務環境、服務質量和服務之間的關系,我們還需要另外的描述。WSDL 文檔可以由其它服務描述文檔來補充,從而描述 Web 服務的這些更高級的方面。例如,描述業務環境除了使用 WSDL 文檔,還要使用 UDDI 數據結構。Web 服務流程語言(Web Services Flow Language,WSFL)文檔中則描述了服務組成和流程。
因為 Web 服務被定義為可以通過 SOAP 從網絡進行訪問,并由服務描述表示,所以該協議棧中的前三層需要提供或使用 Web 服務。最簡單的協議棧將包括網絡層的 HTTP、XML 消息傳遞層的 SOAP 協議以及服務描述層的 WSDL。所有企業間或公用 Web 服務都應該支持這種可交互操作的基礎協議棧。Web 服務,特別是企業內部或專用 Web 服務,能夠支持其它的網絡協議和分布式計算技術。該協議棧提供了互操作性,它使 Web 服務能夠利用現有的互聯網基礎結構。這將使進入普遍存在的環境的成本非常低。另外,靈活性并不會因為互操作性需求而有所降低,因為我們可以為選擇性和增值的技術提供另外的支持。例如,我們必須支持 HTTP 上的 SOAP,但也可以同時支持 MQ 上的 SOAP。
協議棧的最下面三層確立了保證一致性和互操作性的技術,而它們上面的兩層,即服務發布和服務發現,可以用多種解決方案來實現。
任何能夠讓服務請求者使用 WSDL 文檔的操作,不管它處于服務請求者生命周期的哪個階段,都符合服務發布的標準。該層中最簡單、最靜態的實例就是服務提供者直接向服務請求者發送 WSDL 文檔。這被稱為直接發布。電子郵件是直接發布的載體之一。直接發布對靜態綁定的應用程序來說很有用。另外,服務提供者還可以將描述服務的文檔發布到主機本地 WSDL 注冊中心、專用 UDDI 注冊中心或 UDDI 運營商節點。
Web 服務如果沒有被發布就不能被發現,所以說服務發現依賴于服務發布。該層的各種發現機制和一組發布機制互相平行。任何允許服務請求者獲得對服務描述的訪問權,并在運行時使應用程序能夠使用該服務描述的機制都必須符合服務發現的標準。最簡單、最靜態的發現的實例是靜態發現,其中服務請求者從本地文件獲取 WSDL 文檔。這通常都是通過直接發布獲取的 WSDL 文檔,或者前面查找操作的結果。另外,也可以通過使用本地 WSDL 注冊中心、專用 UDDI 注冊中心或 UDDI 運營商節點在設計時或運行時發現服務。因為 Web 服務實現是一種軟件模塊,所以通過組建 Web 服務來產生 Web 服務是很自然的。Web 服務的組合可以扮演很多角色之一。企業內部的 Web 服務可能會相互合作,從而對外顯示出一個單獨的 Web 服務接口,或者,來自不同企業的 Web 服務可以相互合作,從而執行機器到機器、企業到企業的事務。另外,工作流程管理者還可以在參與業務流程的時侯調用每個 Web 服務。最上面一層,即服務流程,描述了如何執行服務到服務的通訊、合作以及流程。WSFL 用于描述這些交互。要使 Web 服務應用程序滿足當今電子商務的迫切需求,就必須提供企業級基礎結構,包括安全性、管理和服務質量。這幾個垂直條在協議棧的每一層都必須得到解決。每一層的解決方案可以彼此獨立。隨著 Web 服務范例的采用和發展,將會出現更多此類垂直條。
該協議棧的最下面幾層表示基礎 Web 服務協議棧,它們相對于協議棧中上面幾層來說更成熟,也更標準。Web 服務的成熟和采用將會帶動協議棧中上面幾層和垂直條的開發和標準化。
網絡層
Web 服務協議棧的最底層是網絡層。該層可表示任意多個網絡協議:HTTP、FTP、SMTP、消息排隊(Message Queuing)、互聯網 ORB 間協議(Internet Inter ORB Protocol,IIOP)上的遠程方法調用(Remote Method Invocation,RMI)、電子郵件等等。在任何給定的情況下使用的網絡協議都依賴于應用程序需求。
對于可以從互聯網訪問的 Web 服務,人們選擇網絡技術的時侯通常會傾向于選擇普遍部署的協議,如 HTTP。對于內部網中提供和使用的 Web 服務,使用另外的網絡技術也會被認同。我們可以根據其它需求選擇網絡技術,包括安全性、可用性、性能以及可靠性。這使得 Web 服務可以利用已有的功能更高級的聯網基礎結構和面向消息的中間件,如 MQSeries。在有多種網絡基礎結構的企業中,HTTP 可以用來在這些基礎結構之間搭建橋梁。
Web 服務的好處之一在于,它為專用內部網和公用互聯網服務的開發和使用提供了統一的編程模型。所以,網絡技術的選擇對服務開發者來說是透明的。
基于 XML 消息傳遞的分布式計算
Web 服務體系結構最基礎的支柱是 XML 消息傳遞。當前 XML 消息傳遞的行業標準是 SOAP。IBM、Microsoft 以及其它企業都向 W3C 建議 SOAP 作為 XML 協議工作組(XML Protocol Working Group)的基礎。XML 協議將代替 SOAP 作為行業標準 XML 消息傳遞協議的位置。當 W3C 發布 XML 協議的草案標準時,Web 服務體系結構就會從 SOAP 遷移到 XML 協議。
SOAP 是一種簡單的、輕量級的基于 XML 的機制,用于在網絡應用程序之間進行結構化數據交換。SOAP 包括三部分:一個定義描述消息內容的框架的信封、一組表示應用程序定義的數據類型實例的編碼規則,以及表示遠程過程調用(remote procedure calls,RPC)和響應的約定。SOAP 可以和各種網絡協議(如 HTTP、SMTP、FTP 和 IIOP 或 MQ 上的 RMI)相結合使用,或者用這些協議重新封裝后使用。
雖然理解這個基礎很重要,但多數 Web 服務開發者不必直接處理這個基礎結構。大多數 Web 服務都會使用從 WSDL 生成的經過優化的特定于編程語言的綁定。當服務提供者和服務請求者都在類似的環境中執行時,這種優化可能尤為重要。
圖 4 展示了 XML 消息傳遞(即 SOAP)和網絡協議如何組成Web 服務體系結構的基礎。

圖 4. 使用 SOAP 的 XML 消息傳遞
網絡節點在基于 XML 消息傳遞的分布式計算中扮演提供者和請求者角色的基本要求是構建、解析 SOAP 消息的能力(或兩者兼而有之),以及在網絡上通信的能力(接收、發送消息,或兩者)。
通常,在 Web 應用程序服務器中運行的 SOAP 服務器將執行這些功能。另外,我們也可以使用在 API 中封裝這些功能的特定于編程語言的運行庫。應用程序與 SOAP 的集成可以通過使用四個基本步驟來實現:
在圖 4 中,服務提供者的應用程序在(1)創建一條 SOAP 消息。這條 SOAP 消息是調用由服務提供者提供的 Web 服務操作的請求。消息主體中的 XML 文檔可以是一個 SOAP RPC 請求,也可以是一個服務描述中所描述的以文檔為中心的消息。服務請求者將此信息和服務提供者的網址一起提供給 SOAP 基礎結構(例如一個 SOAP 客戶機運行時)。SOAP 客戶機運行時與一個底層網絡協議(例如 HTTP)交互,然后在網絡上將 SOAP 消息發送出去。
網絡基礎結構在(2)將消息傳送到服務提供者的 SOAP 運行時(例如一個 SOAP 服務器)。SOAP 服務器將請求消息路由到服務提供者的 Web 服務。如果應用程序需要,SOAP 運行時負責將 XML 消息轉換為特定于編程語言的對象。這個轉換由消息中可以找到的編碼模式所控制。
Web 服務負責處理請求信息并生成一個響應。該響應也是一條 SOAP 消息。響應的 SOAP 消息在(3)被提供給 SOAP 運行時,其目的地是服務請求者。在 HTTP 上的同步請求/響應的情況中,聯網協議的底層請求/響應本質用于實現消息傳遞的請求/響應本質。SOAP 運行時將 SOAP 消息響應發送到網絡上的服務請求者。
響應消息在(4)由服務請求者節點上的聯網基礎結構接收。消息會經過整個 SOAP 基礎結構;可能會將 XML 消息轉換為目標編程語言中的對象。然后,響應消息被提供給應用程序。
本示例使用了請求/響應傳送基本原理,這種原理在大多數分布式計算環境中都很常見。請求/響應交換可以是同步的,也可以是異步的。其它傳送基本原理,如單向消息傳遞(無響應),通知(推動式響應)以及發布/訂閱,也可能用到 SOAP。
那么,服務請求者如何知道請求消息應該使用什么格式呢?這個問題在下面會得到回答。
服務描述:從 XML 消息傳遞到 Web 服務
服務提供者是通過服務描述將所有用于調用 Web 服務的規范傳送給服務請求者的。要實現 Web 服務體系結構的松散耦合,并減少服務提供者和服務請求者之間所需的共識的程度和定制編程與集成的程度,服務描述就是關鍵。例如,不管是請求者還是提供者,都不必了解對方的底層平臺、編程語言或分布式對象模型(如果有的話)。服務描述與底層 SOAP 基礎結構相結合,足以封裝服務請求者的應用程序和服務提供者的 Web 服務之間的這個細節。
基本服務描述
Web 服務體系結構使用 WSDL 作為基本服務描述。WSDL 已經被提交到 W3C 作為標準。WSDL 是一種 XML 文檔,它將 Web 服務描述為一組端點,這些端點會處理包含面向文檔或面向過程的(RPC)消息的消息。操作和消息都是被抽象描述的,然后它們會被綁定到一個具體的網絡協議和消息格式,用來定義端點。相關的具體端點被合并到抽象的端點或服務中。WSDL 可以擴展為允許端點和其消息的描述,不管使用哪種消息格式或網絡協議進行通訊都可以。然而,目前經過描述的綁定只能用于 SOAP 1.1、HTTP POST 以及多用途互聯網郵件擴展(Multipurpose Internet Mail Extensions,MIME)。
Web 服務體系結構中對 WSDL 的使用按照常規將基本的服務描述分成了兩部分:服務接口和服務實現。這使每個部分都可以被分開獨立定義,并可以由另一部分重新使用。

服務接口定義是一種抽象或可重用的服務定義,它可以被多個服務實現定義實例化和引用。我們可以將服務接口定義想象成接口定義語言(Interface Definition Language,IDL)、Java 接口或 Web 服務類型。這使常見的行業標準服務類型可以被多個服務實現者定義和實現。這類似于在編程語言中定義抽象接口然后得到多個具體實現。服務接口可以由行業標準組織定義。
服務接口包含 WSDL 元素,它們組成了服務描述中的可重用部分,這些元素有:WSDL: binding、WSDL: portType、WSDL: message 和 WSDL: type 元素,如圖 5 中所描述。WSDL: portType 元素中定義了 Web 服務的操作。操作定義了輸入和輸出數據流中可以出現的 XML 消息。您可以將操作想象成編程語言中的方法說明。WSDL: message 元素指定哪些 XML 數據類型組成消息的各個部分。WSDL: message 元素用于定義操作的輸入和輸出參數。WSDL: types 元素中描述消息中復雜數據類型的使用。WSDL: binding 元素描述特定服務接口(WSDL: portType)的協議、數據格式、安全性和其它屬性。
服務實現定義是一個描述給定服務提供者如何實現特定服務接口的 WSDL 文檔。Web 服務被建模成 WSDL: service 元素。服務元素包含一組(通常是一個)WSDL: port 元素。端口將端點(例如網址位置或 URL)與來自服務接口定義的 WSDL: binding 元素關聯起來。
為了說明職責的安排,開放應用程序組(Open Applications Group,OAG)為開放應用程序組集成規范(Open Applications Group Integration Specification,OAGIS)購買標準定義了一個服務接口定義。這個服務接口定義會定義 WSDL: type、WSDL: message、WSDL: portType 和 WSDL: binding。
服務提供者可以選擇開發實現 OAGIS 購買訂單服務接口的 Web 服務。服務提供者會開發一個服務實現定義文檔,描述 WSDL 設備、端口和地址位置元素,這些元素描述提供者的 Web 服務的網址及其它特定于實現的細節。
服務接口定義和服務實現定義結合在一起,組成了服務完整的 WSDL 定義。這兩個定義包含為服務請求者描述如何調用以及與 Web 服務交互的足夠信息。服務請求者可以要求獲得其它關于服務提供者端口的信息。此信息由服務完整的 Web 服務描述提供。
完整的 Web 服務描述
完整的 Web 服務描述建立在服務基本的 WSDL 定義之上。完整的 Web 服務描述可以解決這樣的問題:什么企業在托管這個服務?它是何種類型的企業?與服務相關聯的產品有哪些?各種公司和產品類別中與該企業或其 Web 服務相關聯的分類有哪些?有沒有服務的其它方面(如服務質量)會影響到請求者是否選擇調用服務?為了使查找該服務更容易,可以提供哪些關鍵字?
圖 6 中描述了一個完整的 Web 服務描述。
圖 6. 完整的 Web 服務描述協議棧

UDDI 提供了一個保存 Web 服務描述的機制。雖然 UDDI 通常會被認為是一種目錄機制,但是它也定義了一個用 XML 表示服務描述信息的數據結構標準。UDDI 條目中有四種基本數據結構,如圖 7 中所示。
圖 7. 基本 UDDI 數據結構

UDDI 條目由 businessEntity 開始。businessEntity 元素對關于企業的信息進行建模,包括基本的企業信息(例如企業名稱和聯系方式信息是什么?)、分類信息(例如這是何種類型的企業?)以及標識信息(即 Dunn and Bradstreet 編號是什么?)。businessEntity 包含一組 businessService 元素,每個元素對應于企業希望發布的每個 Web 服務。每個 businessService 元素都包含和 businessEntity 元素的 Web 服務有關的技術性和描述性信息。businessService 包含一組 bindingTemplate 元素。bindingTemplate 描述訪問信息(例如端點地址),還描述 businessService 如何使用各種不同的技術規范。技術規范在這里的模型是 tModel。tModel 可以為很多不同概念建模,如:一種服務、一個諸如 HTTPS 之類的平臺技術或一個類別。與 businessService 相關聯的那一組 bindingTemplate 元素代表了 businessService 所使用的技術的印記。
在Web 服務體系結構中,完整的 Web 服務描述包括用于端點描述的一層,這個端點描述使用 UDDI 條目向服務描述添加企業和實現環境。
端點描述遵循結合 WSDL 使用 UDDI 的約定。端點描述使用 UDDI 提供企業信息和類別的標準表示。這個 UDDI-WSDL 約定規定了如何從和 Web 服務相關聯的 UDDI 條目中得出服務接口定義和服務實現定義的 WSDL 描述。這個約定對于在Web 服務體系結構中使用 UDDI 作為基于 WSDL 的服務的服務注冊中心來說至關重要。
端點描述向應用到服務的特定實現的服務描述添加了另外的語義。安全屬性可以定義對 Web 服務的訪問進行控制的策略。服務質量屬性指定面向性能的能力,例如服務在一定時間內作出響應的能力,或所支持的可靠消息傳遞的級別。服務開銷屬性描述服務的資源需求。還可以定義支持哪些對話語義。
服務描述協議棧中的最后一層是協議描述。協議描述反映兩個企業伙伴之間為了完成一個多步企業交互而進行的 Web 服務調用的一個簡單的編排。例如,“協議定義”定義了購買協議中諸如購買者和出售者之類的角色。協議定義規定了每個角色必須達到的要求。例如,出售者必須有接受報價請求(request for quote,RFQ)消息、購買訂單(purchase order,PO)消息和付款消息的 Web 服務。購買者的角色必須有接受報價(RFQ 響應信息)、發票消息和帳戶摘要信息的 Web 服務。這個簡單的 Web 服務到企業角色的編排對于在企業伙伴之間建立多步的、面向服務的交互來說至關重要。在很多不同的企業協議標準下,一個給定的服務請求者或服務提供者也許能夠扮演購買者或出售者的角色。通過顯式地建立企業協議和每個節點在企業協議中扮演各種角色的能力,請求者可以選擇在面對各種提供者企業伙伴時加入哪種企業協議。
這個領域充滿了創新。對于企業協議定義來說,目前還沒有一個單獨的標準。ebXML 協作-協議概要和協定規范(ebXML Collaboration-Protocol Profile and Agreement Specification)描述了這些概念,但不是根據作為該體系結構的一部分描述的 Web 服務技術而描述的。Web 服務流程描述和 Web 服務端點描述這兩層正處于開發中,它們可以提供這個級別的服務描述。
服務描述的發布和發現
服務發布
Web 服務的發布包括服務描述的生成和之后的發布。發布可以使用各種不同機制。
生成服務描述
我們可以生成、手工編碼服務描述,也可以根據已有的服務接口定義組成服務描述。開發者可以手工編碼整個服務描述,包括 UDDI 條目。有些工具可以從編程模型和可執行 Web 服務的部署生成 WSDL,還有可能生成來自元數據構件的部分 UDDI 條目。部分服務描述可能已經存在(例如,Web 服務可以基于一個行業標準服務接口定義),這樣就只須進一步生成一小部分就可以了。
發布服務描述
服務描述可以使用各種不同機制來發布。根據應用程序將使用服務的動態程度,這些不同的機制提供不同的能力。服務描述可以使用多種不同機制發布到多個服務注冊中心。
最簡單的情況是直接發布。直接發布意味著服務提供者直接將服務發布給服務請求者。這可以通過使用電子郵件附件、FTP 站點甚至光盤分發來實現。直接發布可以在企業伙伴雙方就在 Web 上使用電子商務的條款達成一致后進行,或在請求訪問服務的服務請求者支付了費用之后進行。在這種情況下,服務請求者可以保留服務描述的一份本地副本。
稍微更動態一點的發布使用 DISCO 或 ADS。DISCO 和 ADS 兩者都定義了一個從給定 URL 獲取 Web 服務描述的簡單的 HTTP GET 機制。增強的服務描述資源庫會提供服務描述的一個本地高速緩存,不過還提供了附加的搜索能力。對于在企業內部跨越主機的服務描述資源庫來說,服務提供者會向專用的 UDDI 節點發布。我們可以根據發布到節點的 Web 服務的域的范圍,使用幾種專用的 UDDI 節點。
內部企業應用程序 UDDI 節點(Internal Enterprise Application UDDI node)節點:公司內部為了進行內部企業應用程序集成而使用的 Web 服務應該被發布到這一類 UDDI 節點。此類 UDDI 節點的范圍可以是部門的或公司的單獨的應用程序。這些 UDDI 位于防火墻之后,允許服務發布者對他們的服務注冊中心和它的訪問權、可用性以及發布要求有更多的控制。
門戶網站 UDDI 節點(Portal UDDI node)節點:由公司發布以供外部伙伴查找和使用的 Web 服務可以使用門戶網站 UDDI 節點。門戶網站節點運行在服務提供者的防火墻之外或之間。這種專用 UDDI 節點只包含公司希望向來自外部伙伴的請求者提供的那些服務描述。這允許公司保留對他們服務描述的控制、UDDI 節點的訪問以及 UDDI 節點的服務質量。此外,通過使用門戶網站中固有的基于角色的可見性,企業將服務描述的可見性局限在允許看到它們存在的伙伴中。
伙伴目錄 UDDI 節點(Partner Catalog UDDI node)節點:由特定公司使用的 Web 服務可以被發布到伙伴目錄 UDDI 節點。伙伴目錄 UDDI 節點位于防火墻之后。此類專用 UDDI 節點只包含來自合法企業伙伴的經過允許的、測試過的、有效的 Web 服務。此類 Web 服務的業務環境和元數據可以被定位到特定的請求者。
電子市場 UDDI 節點(E-Marketplace UDDI node)節點:對于服務提供者打算用來與其它 Web 服務競爭請求者的業務的 Web 服務來說,服務描述應該被發布到電子市場 UDDI 節點或 UDDI 運營商節點。電子市場 UDDI 節點由一個行業標準組織或社團托管,包含特定行業中的企業的服務描述。我們可以要求這些服務支持特定的標準、可搜索元數據、接口或數據類型。電子市場 UDDI 節點一般會過濾掉某些非法的條目,并提供有保證的服務質量。
UDDI 運營商節點:如果您希望 Web 服務可以被潛在的新的企業伙伴或服務用戶發現,還可以將其發布到 UDDI 運營商節點。IBM、Microsoft 和 Ariba 都支持、復制和托管 UDDI 運營商節點。在發布 UDDI 運營商節點的時侯,如果要讓潛在的服務請求者發現服務的話,完整的業務環境和經過深思熟慮的分類法是很必要的。
圖 8. 服務發現連續體

圖 8 展示了從發布和發現中最靜態、最簡單的技術到最動態、更復雜的技術的連續體。Web 服務的用戶或實現者不必嚴格遵循這個發展順序。
服務發現
Web 服務的發現包括獲取服務描述和使用描述。獲取過程可以使用各種不同機制。
獲取服務描述
和發布 Web 服務描述一樣,根據服務描述如何被發布以及 Web 服務應用程序可能達到的動態程度,獲取 Web 服務描述也會有所不同。服務請求者將在應用程序生命周期的兩個不同階段,即設計時和運行時查找 Web 服務。在設計時,服務請求者按照他們支持的接口類型搜索 Web 服務描述。在運行時,服務請求者根據他們通訊的方式或公告的服務質量搜索 Web 服務。
使用直接發布方法時,服務請求者在設計時對服務描述進行高速緩存,以在運行時使用它。服務描述可以被靜態地用程序邏輯表示,并存儲在文件或簡單的本地服務描述資源庫中。
服務請求者可以在設計時或運行時在服務描述資源庫(簡單的服務注冊中心或 UDDI 節點)中檢索一條服務描述。查找機制需要支持一種查詢機制,它提供按接口類型(基于 WSDL 模板)、綁定信息(即協議)、屬性(如 QoS 參數)、所需的中介類型、服務分類法、企業信息等等的查找。
不同類型的 UDDI 節點會顯示可以選擇的運行時綁定 Web 服務的數目、多選一的策略,或者調用服務之前必須由請求者作出預選的量。
內部企業應用程序 UDDI 節點和伙伴目錄 UDDI 節點將不需要預選來建立對服務的信任。服務選擇可以建立在綁定支持、歷史性能、服務質量分類、相似性或負載平衡的基礎之上。
電子市場 UDDI 節點將有更多的運行時服務可以選擇。必須執行某種預選以保證 Web 服務提供者是有價值的伙伴。我們可以根據價格承諾、開銷、經過允許的伙伴列表的出席情況,同樣還有綁定支持、歷史性能、服務質量分類和相似性來選擇服務。
如果服務請求者從 UDDI 運營商節點查詢 Web 服務提供者,他們在預選可能的服務提供者時就必須盡可能謹慎和認真。應該有一個有效和準確的機制就位,過濾掉無用的服務描述和沒有價值的服務提供者。
使用服務描述
在獲取了服務描述之后,服務請求者需要處理它以調用服務。服務請求者使用服務描述生成對 Web 服務的 SOAP 請求或特定于編程語言的代理。該生成可以在設計時或運行時進行,從而對 Web 服務的調用進行格式化。我們在設計時和運行時可以使用各種工具從 WSDL 文檔生成編程語言綁定。這些綁定表示應用程序的 API,并封裝了來自應用程序的 XML 消息傳遞的細節。
在下一部分,我們將描述基本 Web 服務體系結構的擴展,電子商務需要這些擴展才能使用 Web 服務。
在下一部分,我們將描述基本 Web 服務體系結構的擴展,電子商務需要這些擴展才能使用 Web 服務。
14.3.2 真正的電子商務的 Web 服務
雖然對于可互操作的 XML 消息傳遞來說 SOAP 和 HTTP 就足夠了,而且 WSDL 也足可以傳達服務請求者和服務提供者之間需要什么樣的消息,但是要覆蓋電子商務的全部需求還需要更多的技術。為了完全支持電子商務,安全性、可靠的消息傳遞、服務質量、Web 服務協議棧的每一層的管理都需要擴展。
安全性
真的需要 Web 服務安全層嗎?對于基于消息的體系結構,業界已經有一套現成的而且廣泛接受的傳輸層安全機制,比如,安全套接字層(Secure Sockets Layer,SSL)和網際協議安全(Internet Protocol Security,IPSec),為什么還要再加別的呢?為了回答這個問題,我們不僅要研究要求,還將探討一些只依靠現有的幾類傳輸層安全機制并不能在 Web 服務模型內提供足夠的安全性的情況。
通常,Web 服務安全層必須提供以下四個基本的安全性要求:
機密性(Confidentiality)是指信息對沒有經過授權的個人、實體或進程的不可用性或不公開性,并保證消息內容不對沒有經過授權的個人公開。
授權(Authorization)是指權限的授予,包括根據訪問權限授予訪問權和保證發送方被授權發送消息。
數據完整性(Data integrity)是指數據沒有以未經授權的方式或被未經授權的用戶不可察覺的改變或者破壞的性質,從而確保消息在傳送的過程中不會被偶然或故意修改。
原始性證明(Proof of origin)是對消息或數據的發送者進行標識的證據。斷言消息由正確標識的發送者傳送,并且不會重新發送以前傳送過的消息。這一要求隱含了數據完整性的要求。
由于需要在基于 XML 消息和工作流的動態 Web 服務世界中管理不同風格的資源訪問,所以必須重新評估策略、信任和風險評估這三者相互之間的關系。現有的基于個人身份的訪問控制模型正在發展成為基于角色的信任域關系,在該種關系中,可信任的權威機構將執行某項任務的權限授予個人,其行為受該權限限制。Web 服務體系結構定義了需要信息的代理(服務請求者)、提供信息的代理(服務提供者),有時還有提供關于信息的信息的代理(服務中介者、元信息提供者或服務注冊中心)。服務中介者經常會收到大量信息請求,這樣就需要它能夠決定誰想要哪些信息以及請求者是不是已經被授予訪問權。基礎設施和關系變化迅速,因此有關的策略需要能靈活的允許或拒絕訪問。
此外,盡管 XML 發誓要為這樣的服務提供通用接口,但 XML 不會提供實現這一夢想所需要的整個基礎設施。而且,XML 可能不適合構建整個 Web 服務安全層。目標是要確定在哪些場合用 XML 格式提供信息以顧及通用數據交換較為重要,以及在哪些場合利用目前已存在于平臺之上的現有安全性機制較為重要。
SOAP 信封是用 XML 定義的,從而使您可以向消息添加種類眾多的元信息,比如事務 ID、消息路由信息和消息安全性。SOAP 信封由兩個部分組成:頭和主體。頭是把功能添加到 SOAP 消息中的通用機制。SOAP 頭元素下一級的所有子元素都叫做頭條目。主體是為最終的消息接收方想要的應用數據(如 RPC)準備的容器。因此,可以把 SOAP 看作是在傳輸層(例如 HTTP)和應用層(例如,業務數據)之間引入的另外一層,在此可以方便的傳送消息元信息。SOAP 頭提供可擴展機制以擴展 SOAP 消息使其可以適用于多種用途。雖然 SOAP 頭是向消息添加安全性功能最合理的地方,但是 SOAP 規范本身并沒有指定這樣的頭元素。
讓我們仔細的分析一下在 Web 服務模型中現有的各種各樣的傳輸層安全機制為什么不夠,又為什么會需要 Web 服務安全層,以及這個安全層最初是怎樣的。
端對端的消息傳遞。安全傳輸協議,如 SSL 和 IPSec,可以在傳輸過程中提供消息完整性和機密性,但只有在點對點的情況下,它們才會這樣做。但是,因為 SOAP 消息是由中介體接收并處理的,所以即便兩兩之間的通信鏈路(communication link)是可信任的,只要在所有的中介體間沒有信任關聯(trust association),那么安全的端對端通信就是不可能的。如果有一條通信鏈路不安全,那么端對端安全性也會被削弱。就 Web 服務拓撲來看,安全的傳輸對于 SOAP 消息的端對端安全性是不夠的。
中間件的獨立性。最終,唯一能提供端對端安全性的方式就在于應用層或中間件層。如果消息在通信方之間的某點是純文本,那么就有可能在這點受到攻擊。但是,既要在新的或現有的應用中集成加密功能,又不能引入額外的安全性弱點或增加風險,這是一項不容易又不受歡迎的任務。因此,在大多數情況下,人們希望安全性功能盡可能靠近應用,但不在應用本身中構建。
傳輸的獨立性。SOAP 中介體的原意是用來把信息轉發到不同的網絡上去,通常使用的傳輸協議也會有所不同。雖然所有的通信鏈路都是安全的,中介體也是值得信賴的,但是,安全信息(如消息發送者的身份驗證)需要被轉移到消息路徑上的下一個傳輸協議安全性域,這個過程冗長而且復雜,還可能會導致完整性方面的缺陷。
異步多階消息傳遞。傳輸層安全性保證數據在通信鏈路上傳輸時的安全。它與存儲在任何中介體上的數據都無關。在一次傳輸被接收并解密后,傳輸層安全性對保護數據免受沒有經過授權的訪問和可能的改變就不是很有幫助了。在先存儲消息然后轉發的情況下(持久的消息隊列),消息層保護是有必要的。
因為我們已經看到安全的傳輸機制不足以滿足 Web 服務開發方法和使用場景的要求,所以我們的任務就是要創建一個概念性 Web 安全層,包括下列幾個組件:
對于網絡安全性:
支持如 SSL 和 HTTPS 等提供機密性和完整性的安全傳輸機制。
對于 XML 消息:
如果通信沒有中間節點,那么發送方可以依靠 SSL 或 HTTPS 來保證用戶標識和密碼的機密性。
W3C 正在標準化 XML 數字簽名工作的支持。它定義了生成消息摘要與利用發送方的私鑰來簽發消息的標準 SOAP 頭和算法。因此,接收方就可以證明消息發送方的身份。
對網絡內部的、可信任的第三方驗證服務(例如 Kerberos)的支持。
概念性 XML 消息傳遞模型還必須支持端對端保護消息及其子元素。為了全面的支持,過程和流能力需要被擴展到包括消息交換的安全性特征。應該有一種方式可以定義多段消息和用預期接收方的公鑰來保護消息段。需要探討的一些論題有:
端點負責實現驗證及授權。應該支持在企業之間交換信息的合同的任何描述中都要定義哪些雇員可以使用哪些服務。中介體負責審計和服務原始性證明。中介體還可能需要執行驗證、授權和數字簽名驗證以及有效性檢查。
在服務端點的服務描述層中需要定義支持上文論述的安全性問題的面向安全性元數據。這些安全性描述將根據主體或角色定義 Web 服務層訪問控制。服務描述將會描述是否支持數字簽名、加密、驗證和授權以及如何支持它們。
請求者將使用服務描述的安全性元素來查找服務端點,該端點應符合政策要求及其安全性方法。
標準組正在調查如下主題和技術。隨著這些標準固定下來,它們將會被并入 Web 服務安全性體系結構。
W3C 有一個 XML 加密工作組,幫助提供數據元素的機密性,這樣驗證交換成為可能。
W3C 已發布了一個 XML 密鑰管理服務(XML Key Management Services,XKMS)的備忘錄,來幫助分發及管理在端點之間進行安全的通信所需的密鑰。
OASIS 已經成立了一個技術委員會來定義授權和驗證斷言(Authorization and Authentication assertions,SAML)。這將幫助端點接受和決斷訪問控制權。
OASIS 已經成立了一個技術委員會來標準化訪問控制權的表達(XACML)。這將幫助端點能夠以一致的方式解析 SAML 斷言。
隨著我們不斷的研究 Web 服務模型中遇到的所有威脅和對策,Web 服務安全性體系結構也在不斷發展著。
服務質量(QoS)和可靠的消息傳遞
服務質量垂直塔提供與 Web 服務概念棧每一層有關的信息的規范。對于網絡層,這將會暗示能使用各種級別的服務質量的網絡。
由于需要通過網絡進行可靠的消息傳遞,所以得根據在這一領域內發送高質量服務的能力來選擇網絡技術。可靠的消息傳遞指基礎設施把消息一次發送(只發送一次)到預定目標或提供確定的事件(如果發送沒能完成,也許會重新發送到源)的能力。結合網絡層與 XML 消息傳遞將需要支持四個等級的消息傳遞服務質量:
1. 最佳努力:服務請求者發送消息,服務請求者和基礎設施不嘗試重發。
2. 至少一次:服務請求者提出請求,并一直重試直到它接收到確認為止。服務提供者重復消息處理不是問題,例如簡單的查詢處理。實現這可能意味著每個消息包含唯一的標識。服務請求者以自己確定的時間間隔重發沒有得到確認的消息。服務提供者發出確認消息,為 RPC 響應消息,如果不能處理的話,就發送不能處理的消息異常。
3. 至多一次:這建立在最少一次情況的基礎之上。服務請求者試著請求直到它得到回應。象現有的全局唯一標識符(universal unique identifier,UUID)這樣的機制允許服務提供者抑制重復多次的請求,以確保請求不會被多次執行。例如,請求根據庫存目錄中的一個號碼拿一件東西。
4. 剛好一次:服務請求者提出請求,請求已經執行的回應使其得到保證。剛好一次交換模式排除了重傳請求的需要并且適應失效的情況。
可靠的消息傳遞通常是通過標準設計模式傳送的,在該模式中,一件基礎設施,有時叫做端點管理器,將會被用來在通信的每一端協調消息發送。在這種模式中,發送方通過同步請求把消息發給端點管理器。一旦發送到,發送方就可以得到保證,一定會把消息發送出去或引發確定的事件(例如超時)。端點管理器與其它資源管理器參與本地事務,在一次事務中不僅可以由端點管理器對消息進行排隊,還有可能在數據庫中記錄業務過程步驟。應用程序應該指派端點管理器來負責發送消息或者檢測發送失敗的原因,它在網絡傳輸層或 XML 消息傳遞層都可以起作用。
可靠的一次性消息發送的技術和目的都不會引起爭議。但是,圍繞如何在 SOAP 和 XML 的上下文中支持這項技術已經提出了重要的質疑。關鍵問題是:應不應該在 XML 消息層上定義必要的協議和消息格式,從而允許可靠的消息發送成為兩端應用程序的責任,或者能不能在較低的層(如傳輸層上)定義協議和消息格式?
在沒有支持可靠的消息傳遞的傳輸方式的情況下(即互聯網),XML 消息傳遞層將需要在不可靠的基礎設施之上支持這些服務質量。端點管理器將需要修改消息,而不是修改消息的傳輸信封,這樣才能成功扮演其角色。應用程序和業務過程的定義將必須考慮所有可能的結果,如拒收消息或在可接受的時間長度內發送不出去。但是,這些定義還需要考慮在發送過程中發生的中間狀態。向業務過程公開這些狀態可能會大大增加其定義的復雜程度,但對于定義過程的業務分析師而言并無太大意義。在一些情況下,使用 XML 消息傳遞來發送可靠的消息傳遞格式可能會導致使用現有的這些傳輸毫無效率。最好能開發一種在互聯網上使用的可靠的 HTTP 標準。
在有支持可靠的消息傳遞的傳輸方式的情況下(即在企業內部),它可以用于發送可靠的消息,而不是 XML 消息傳遞層(可能缺省為空實現)。端點管理器將會只修改傳輸信封,而不會修改 XML 消息。使用可靠的傳輸使應用程序和業務過程定義不需要知道或處理消息發送的中間狀態。
需要在將來進行的幾點補充:
互聯網的 HTTP 需要加以改進才能提供可以在企業間使用的簡單可靠的消息傳遞。這會帶來額外的好處:不止 SOAP,許多種消息類型都可以采用可靠的消息傳遞。需要 XML 消息傳遞層處理可靠的消息傳遞的情況就會隨之減少,促進不依賴于網絡選擇的應用程序開發。
HTTP 上的 XML 消息傳遞層也需要處理發布和訂閱、消息排序、發送時間限制、優先級和多點傳送等等問題。
服務提供者對可靠的消息傳遞的質量和實現的支持情況將會在服務描述的綁定信息中定義。
服務實現層(例如,通過事務的或安全的 SOAP 綁定)的服務描述以及接口層(例如,從請求者開始等待來自提供者的響應之后最長經過多久)的其它服務描述中都會關系到服務質量(Quality of Service)信息。人們期待著開發出 WSDL 擴展或新的服務描述層來允許指定其它服務質量和功能的規范。
Web 服務層上的服務質量可以在服務合成和服務流中使用。在為流選擇服務或提示流管理器該開始恢復或其它的流時,預期的執行時間、超時值、歷史平均執行時間值都可以作為輸入。服務描述棧的端點描述層和工作流描述層必須提供這一信息。
Web 服務的服務質量問題和解決方案仍然很緊迫。
系統和應用程序管理(Management)
隨著 Web 服務成為商業運作的重要因素,就需要對其進行管理。在這種情況下,所謂管理是指專為應用程序定制的或從廠商那里買來的管理應用程序可以發現 Web 服務的基礎設施、Web 服務、服務注冊中心和 Web 服務應用程序存在性、可用性以及健康度。最令人滿意的結果是管理系統還應當能夠控制和配置基礎設施及組件。
管理概念性 Web 服務棧各層的 Web 服務和 Web 服務模型組件必定是有可能的。對管理的需求可以分成兩個集中的領域。第一個領域是用于實現 Web 服務的基礎設施的可管理性。主要的考慮應當是確保可用性和提供服務描述、消息傳遞和網絡的關鍵元素的性能。Web 服務基礎設施提供者應當提供這一層上的系統管理。
企業對其自己的基礎設施及管理擁有完全的自主權。但是,當企業在對等基礎上相互作用時,就應當提供對網絡層、XML 消息傳遞層、服務注冊中心和 Web 服務實現的基本報告和恢復辦法。此外,企業向其合伙人提供的管理接口應當是在服務層上操作的,而不是在相對低級的基礎設施層上。合伙人應該能夠訪問到報告操作和請求處理的狀態和健康度的接口,但不一定要理解企業如何管理其請求的細節。
對于網絡層,現有的網絡管理產品幾乎支持目前所有的網絡基礎設施。這些產品應當用于管理企業內部的 Web 服務的網絡基礎設施。當企業相互作用時,就應該向其合伙人提供有關 Web 服務基礎設施可用性的基本報告。影響 Web 服務基礎設施可用性的網絡可用性應作為因素之一寫入報告。
在 XML 消息傳遞層,協議應該在企業內部由現有的基礎設施管理工具來管理。在企業相互作用的情況下,每個站點都有必要提供協議的基本報告和恢復辦法。例如,如果站點 A 支持會話,就該向站點 B 提供可用于查詢活躍的 IBM Software Group Architecture Overview Web Services Conceptual Architecture 28 會話以及強行回滾的接口。協議層需要正常的頻道與協議和類似對等的控制接口。
管理的第二個方面是 Web 服務本身的可管理性。一些主要的考慮是性能、可用性、事件和使用量度,因為它們將為服務提供者市場收取所提供的服務使用費提供必要信息。
服務描述可以用于宣傳可管理性特征和管理需求。這方面的約定正在開發之中。
服務注冊中心的任何實現,不管是用于私人消費還是公共消費,都要求基礎設施是可用的、發送承諾的服務質量并能夠報告使用情況。這些系統管理元素對于成功采用 UDDI 是十分重要的。
對于 Web 服務應用程序組件來說,支持管理環境可能會大大增加應用程序的復雜性。由于 Web 服務必須易于開發,所以必須盡可能向開發者隱藏這樣的復雜性。Web 服務的管理方式要使基礎設施能自動提供量度、審計日志、啟動和停止處理過程、事件通知和作為 Web 服務運行時的一部分(也就是說,起碼是 SOAP 服務器)的其它管理功能。因為基礎設施通過觀察它所托管的組件的行為不可能收集到所有的信息,所以 Web 服務實現也許會需要向托管它的服務器提供基本的健康度和監督信息。
Web 服務基礎設施應該為服務提供一種簡單的方式以參與管理和利用管理基礎設施。可管理的服務的 WSDL 文檔的定義應當是 Web 服務能實現提供通過管理系統訪問 Web 服務的管理信息的功能。這一接口可能包括的能力是獲得配置和量度數據、更新配置及接收來自可管理的 Web 服務的事件。
Web 服務體系結構的平臺獨立性使它不適合套用任何一條 Web 服務管理標準。因此,需要有一種基于 Web 服務而且允許 Web 服務與管理系統通信的方法。為了達到這一目的,還應當定義由 WSDL 文檔描述的、可接收來自可管理 Web 服務的事件以及量度更新的管理服務,并使其可用。管理服務的實現技術與 Web 服務無關。但是,對于基于 Java 技術的環境,Java 管理擴展(Java Management Extension,JMX)應該是合乎邏輯的而且廠商不可知的選擇。通過使用 JMX 這樣的開放標準,對現有的系統管理提供者來說,要把其目前所提供的產品擴展為包括 Web 服務關鍵元素的管理應該是很容易的。Web 服務的管理體系結構仍在向前發展。
14.4 Web Services 項目實戰
14.4.1 Web Services實現
本書是重點講解EJB 3.0的。在理解了Web Services原理之后, 接下來我們講解如何使用J2EE和EJB3.0來實現Web Services
Web 服務遵循 Java 2 平臺,企業版(Java 2 Platform,Enterprise Edition,J2EE)、通用對象請求代理體系結構(Common Object Request Broker Architecture,CORBA)以及其它針對與耦合較緊的分布式或非分布式應用程序集成的標準。Web 服務是部署并提供通過 Web 訪問業務功能的技術;J2EE、CORBA 和其它標準是實現 Web 服務的技術。
J2EE 1.4為使用常規Java類或企業級Java Beans來創建和部署web services提供了一個全面的平臺。以下表格給出了J2EE 1.4中包括的web service APIs的細節。

定義在Java Community Process的JSR 101之下的JAX-RPC,提供了創建和訪問web services的Java API,因此它是使用J2EE平臺創建和部署web services的“心臟和靈魂”。通過向應用程序開發者隱藏XML類型和Java類型映射的復雜性,以及處理XML和SOAP消息的底層細節,它提供了一個簡單的,健壯的創建web services應用的平臺。為了引入一個方法調用范式,它提供了兩種編程模式:服務器端模式,使用Java類或無狀態EJB開發web service 端點,和客戶端模式,創建作為本地對象訪問web services的Java客戶端。JAX-RPC 1.1要求使用SOAP 1.1,并且實現與使用其他技術創建的web services之間的互操作性,比如微軟的.NET。實現了J2EE1.4規范的應用服務器,比如OC4J 10.1.3和SUN的Java System Application Sever,提供了對于JAX-RPC的支持。
JAX-RPC的叫法有點用詞不當,因為它既支持RPC類型的web services,也支持文檔類型的web services。
Web Services部署模型
在J2EE 1.4之前,所有J2EE商家都使用他們私有的部署模型支持web services。J2EE 1.4為Java Web Services定義了部署模型。它為J2EE平臺上的web services制定了開發,部署以及服務發布和使用的標準。
有了J2EE 1.4對web services的支持,讓我們學習使用J2EE平臺來建造web service的方法。
使用J2EE創建一個Web Service
把web service創建成一個輕便的和可互操作的分布式組件不是一項瑣碎的任務。如之前討論的,你既可以把常規Java類,也可以把無狀態EJB部署成web services。常規Java類被打包在一個web模塊中,而EJB web services被打包在標準的ejb-jar模塊中。
在這兩種部署選擇中,你會使用哪一個呢?
Java 類對無狀態EJB:永無止境的爭論
你會選擇常規Java類還是EJB作為你創建web service的技術可能是一個長期的爭論。Java類比EJB更容易開發,它是純的Java對象,并且它不具有EJB帶來的“額外輜重”。但是,EJB提供了幾個很好的特點,比如被聲明的事務和安全性,因此它使開發者將精力集中于建立商業邏輯,而不需要擔心基礎服務架構。EJB 3.0大大簡化了設計模型,在它的規范中,EJB看起來就像常規Java類。
使用J2EE 5.0簡化SOA的開發
使用J2EE創建面向服務的應用程序確實很困難,因此通過使用由JSR 181定義的Web Services 元數據注解,J2EE 5.0將使開發更簡單。EJB 3.0和Web Services元數據具有相似的目標,就是向開發者提供親和力。
為了在J2EE 1.4中開發一個簡單的Java web service,你需要幾個web service定義文件:WSDL,映射文件和幾個冗長的標準以及私有的web services部署描述符。Web Services元數據規范使用一種類似于EJB 3.0的缺省配置方法來使開發更簡便。Web Services元數據注解處理器(或web services 裝配工具)會為你生成這些文件,因此你只需要關心類的實現。
當你使用Web Services元數據開發時,這是一個看起來如此簡單的Java web service:
package com.ascenttech.ejb30.ws.demo;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(name = "HelloWorldService",
targetNamespace = "http://hello/targetNamespace" )
public class HelloWorldService {
@WebMethod public String sayhello(String name ) {
return "Hello” +name+ “ from jws";
}
}
正如我之前提到的,EJB 3.0使用常規Java類簡化了EJB的開發。通過利用EJB 3.0和Web Services元數據,開發基于EJB的web services將會變得越來越簡單。當使用EJB 3.0和web services元數據時,這是一個看起來如此簡單的HelloWorld EJB web service。你不必擔心創建WSDL,部署描述符等等,應用服務器會在部署過程中生成這些定義文件。
package com.ascenttech.ejb30.ws;
import javax.ejb.Remote;
import javax.jws.WebService;
@WebService
public interface HelloServiceInf extends java.rmi.Remote{
@WebMethod java.lang.String sayHello(java.lang.String name)
throws java.rmi.RemoteException;
}
如下是EJB 3.0中 HelloWorld EJB的實現類:
package com.ascenttech.ejb30.ws;
import java.rmi.RemoteException;
import javax.ejb.Stateless;
@Stateless(name="HelloServiceEJB")
public class HelloServiceBean implements HelloServiceInf {
public String sayHello(String name) {
return("Hello "+name +" from first EJB3.0 Web Service");
}
}
以上例子清楚的表明了通過使用web services元數據和EJB 3.0,服務開發正在變得越來越簡單。現在,你可以在實現了J2EE規范的應用服務中,比如JBoss Application Server等,開始創建和部署你的web services了。
14.4.2 Web Services 項目實戰
14.4.2.1 Web Services的實現
本節使用EJB 3.0 實現一個web Services登錄的例子。下面我們創建一個工程叫:EmployeeManager。加入用到的EJB 3.0的jar包。
我們先創建服務器端的實體Bean,這和創建普通的Ejb3.0實體bean是一樣的:
package com.ascent.ejb.po;
import java.io.Serializable;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@SuppressWarnings("serial")
@Entity
@Table(name = "usr")
public class User implements Serializable
{
private Integer id;
private String name;
private String password;
private String description;
@Id
@GeneratedValue
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
@Column(name = "name", nullable = false)
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Column(name = "password", nullable = false)
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
@Column(name = "description", nullable = true, length = 100)
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
}
接著創建遠程接口:
package com.ascent.webservice.bean;
import java.rmi.Remote;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style=Style.RPC)
public interface LoginDao extends Remote {
@WebMethod
public boolean isLogin(String name, String password);
}
在LoginDao類中要注意的是Remote接口是要實現的,@SOAPBinding(style=Style.RPC),Soap的綁定方式也是需要的,不然在客戶端是找不到LoginDao 。
下面創建會話bean:
package com.ascent.webservice.bean;
import java.util.List;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@Stateless
@WebService(endpointInterface = "com.ascent.webservice.bean.LoginDao")
public class LoginDaoBean
{
@PersistenceContext
protected EntityManager em;// the manager of entity
public boolean isLogin(String name, String password)
{
// define query sentence
StringBuffer hql = new StringBuffer();
hql.append("from User u where u.name='" + name + "'");
hql.append(" and u.password='" + password + "'");
// create the query
Query query = em.createQuery(hql.toString());
List queryList = query.getResultList();
// if the result is null
if (queryList.size() == 0)
{
return false;
}
// if the user's length greater 1
if (queryList.size() > 1)
{
return false;
}
// return single user
return true;
}
}
至此服務器端的類是建好了,這里又兩個問題,需要說明一下
A. 兩個類的方法中都沒有拋出異常,可不可以拋出呢? 可以。但到實現SOA的時候會有一些問題,就是異常在經axis 通過WSDL2Java 生成后,在程序運行時有可能會出現找不到的情形。所以本文為了讓大家在仿照這個例子時都能成功,所以也就拋棄了異常的拋出。
B. 兩個類的方法的返回值是基本類型,而不是自定義類型,為什么會這樣呢,自定義類型可以不可以呢,可以。
現在我們的webservice的服務器端就已經創建好了,我們把服務器端的三個類和persistence.xml文件一起打包部署到jboss服務器里。包名是:empdEjb。
下面我們來創建客戶端:
package com.ascent.webservice.client;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import com.ascent.webservice.bean.LoginDao;
public class LoginClient
{
public static void main(String[] args) throws Exception
{
String userName ="lxl";
String password = "lxl";
URL url = new URL("http://localhost:8080/empdEjb/LoginDaoBean?wsdl");
QName qname =
new QName("http://bean.webservice.ascent.com/jaws","LoginDaoService");
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(url, qname);
LoginDao loginDao = (LoginDao) service.getPort(LoginDao.class);
boolean isExists = loginDao.isLogin(userName, password);
if(isExists)
{
System.out.println("hello " + userName);
}
else
{
System.out.println("sorry " + userName + ", you are not user in the system!");
}
}
}
把服務器端發布出去以后,服務器端會自動發布一個webService,并且生成并發布一個WSDL文件,通過訪問http://localhost:8080/empdEjb/LoginDaoBean?wsdl這個網址是可以找到的。http://bean.webservice.ascent.com/jaws 和 LoginDaoService 字符串,在客戶端程序當中出現了上面兩個字符串,它們在你生成的wsdl 文件中有詳細的描述。在地址欄里輸入http://localhost:8080/empdEjb/LoginDaoBean?wsdl,就可以看到wsdl文件了。這里你所需要做的是按照你自己的情況編寫你自己的客戶端程序。啟動服務器后,在機子上運行客戶端程序就可以了。當然你也可以去編寫自己的jsp客戶端去調用它。wsdl文件的內容如下:
<definitions name="LoginDaoService"
targetNamespace="http://bean.webservice.ascent.com/jaws">
<types/>
<message name="LoginDao_isLogin">
<part name="String_1" type="xsd:string"/>
<part name="String_2" type="xsd:string"/>
</message>
-
<message name="LoginDao_isLoginResponse">
<part name="result" type="xsd:boolean"/>
</message>
-
<portType name="LoginDao">
-
<operation name="isLogin" parameterOrder="String_1 String_2">
<input message="tns:LoginDao_isLogin"/>
<output message="tns:LoginDao_isLoginResponse"/>
</operation>
</portType>
-
<binding name="LoginDaoBinding" type="tns:LoginDao">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
-
<operation name="isLogin">
<soap:operation soapAction=""/>
-
<input>
<soap:body namespace="http://bean.webservice.ascent.com/jaws" use="literal"/>
</input>
-
<output>
<soap:body namespace="http://bean.webservice.ascent.com/jaws" use="literal"/>
</output>
</operation>
</binding>
-
<service name="LoginDaoService">
-
<port binding="tns:LoginDaoBinding" name="LoginDaoPort">
<soap:address location="http://lixinli:8080/empdEjb/LoginDaoBean"/>
</port>
</service>
</definitions>
這樣一個WebService+Ejb 3.0的例子就實現了。
14.4.2.2 SOA的實現
本例還是基于前兩個例子的基礎上的,要保證上面的例子是能正常運行的。
1.WSDL2Java
從名字上可以看出,是把wsdl 轉化為java的.在上面的例子中我們在服務器端生成了一個wsdl文件,現在要做的就是你把那個wsdl文件給別人或者別的公司,讓他們根據wsdl中所描述的你所提供的服務,去開發一個應用,來訪問你所提供的接口。拿到這個WSDL文件后要做什么呢,to java。我們來看看怎么to java。
這里,在原來的EmployeeManager工程下面建一個wsdl文件夾,將它放在下面,然后所要做的準備工作是,把包括axis在內的幾個jar包找到,設置在你的classpath里面。然后在命令行下運行WSDL2Java。
哪幾個jar包?
C:\axis-1_4\lib\axis.jar;C:\axis-1_4\lib\axis-ant.jar;C:\axis-1_4\lib\commons-discovery-0.2.jar;C:\axis-1_4\lib\commons-logging-1.0.4.jar;C:\axis-1_4\lib\jaxrpc.jar;C:\axis-1_4\lib\log4j-1.2.8.jar;C:\axis-1_4\lib\saaj.jar;C:\axis-1_4\lib\wsdl4j-1.5.1.jar;E:\jboss-4.0.5\server\default\lib\activation.jar;E:\jboss-4.0.5\server\default\lib\mail.jar
這是我classpath 里面所設置的幾個jar包,后面兩個可以不需要,第二個也可以不需要,后倆個只是保證運行的時候沒有警告。
1. 將LoginDaoBean.wsdl 放在wsdl文件夾下面。E:\workspace\EmployeeManager\wsdl
2. 在命令行下進入E:\workspace\EmployeeManager\wsdl
3. 執行 java org.apache.axis.wsdl.WSDL2Java LoginDaoBean.wsdl
這個時候,你會發現在wsdl文件夾下面生成了一個目錄,它里面包含了幾個java類。
LoginDao.java,LoginDaoBindingStub.java,LoginDaoService.java,LoginDaoServiceLocator.java
2 SOA的實現
本節是一個以SOA+struts實現登錄的例子。新建一個web工程,EmployeeWebService,然后將上面生成的幾個類放入你的src目錄下面,是放整個目錄,別只放幾個類進去. 構建struts資源。創建struts的過程就不在這里細說了。創建的action內容如下:
package com.ascent.webservice.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.ascent.webservice.struts.form.LoginForm;
import com.ascent.webservice.bean.jaws.LoginDao;
import com.ascent.webservice.bean.jaws.LoginDaoServiceLocator;
public class LoginAction extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginForm loginForm = (LoginForm) form;
String userName = loginForm.getLoginName();
String password = loginForm.getPassword();
LoginDaoServiceLocator loginDaoServiceLocator = new LoginDaoServiceLocator();
LoginDao loginDao=
loginDaoServiceLocator.getLoginDaoPort();
boolean isExists = loginDao.isLogin(userName, password);
if(isExists)
{
System.out.println("hello " + userName);
HttpSession session = request.getSession();
session.setAttribute("loginName", loginForm.getLoginName());
return mapping.findForward("success");
}
else
{
System.out.println("sorry " + userName + ", you are not user in the system!");
ActionMessages messages = new ActionMessages();
messages.add("login",new ActionMessage("error.login.jsp.loginName.exists"));
this.saveErrors(request, messages);
return mapping.getInputForward();
}
}
}
這里用到的LoginDaoServiceLocator類和getLoginDaoPort()方法就是使用WSDL2Java命令把wsdl文件生成的類。現在就可以打包成叫employee的war文件,運行它。至此,你便可以在瀏覽器中輸入http://localhost:8080/employee/login.jsp,運行你這個SOA的應用了。如果是把服務器端部署到別的機器上,只要把localhost改為相應的ip就可以了。
小結
本章首先介紹了目前一個前沿技術:Web Services和面向服務的軟件架構(Service Oriented Architecture,簡稱SOA)。在理解了Web Services原理之后, 接下來我們講解了如何使用J2EE和EJB3.0來實現Web Services。