用Java Web服務打造聊天程序
Web服務是什麼或者應該是什麼有許多定義,每個或多或少都可以理解。很有趣的事情是最簡單的東西往往是最難描述的。眼前就有一個很好的例子:一個Web服務是一個可以和外部世界交換文檔的實體。這個實體是自我描述的並且擁有一個唯一的特性。
這個文檔內容是XML;嚴格來說是SOAP。SOAP(簡單對象存取協議)定義Web服務消費和生成的XML文檔的內部結構。SOAP被認為是一個行業標準並且被許多跨平台軟件供應商、硬件平台、操作係統或者編程語言廣泛地采用。
每個Web服務都有一個地址。這是它的ID。這個地址由一個URI(亦稱URL)定義。一個Web服務存在於並且被它的URI標識。這個地址經常被稱為一個終端。這個ID和內容的安全性毫無關係。本教程的服務存在於http://localhost:6060/ChatService/。
Web服務帶有它自己的描述。這告訴你它交換的是什麼類型的文檔。它說明了服務存在於什麼地方(URI地址)。並且它還說明了它可以使用哪個傳輸協議來交換文檔。Web服務描述使用的語言是WSDL(Web服務定義語言)。一個Web服務完全由它的WSDL文檔描述。為了和一個獨立Web服務通訊,你隻需要WSDL文檔。即使WSDL在它自己的上下文中描述Web服務,它還是無法描述多個Web服務組合起來所形成的美妙的樂章。
Web服務有一個地址,但是為了訪問它,你需要發現它在哪兒。換句話說,你需要一個電話號簿列表Web服務。UDDI (通用描述、發現和集成)是行業標準的電話號碼薄。UDDI處理寄存器並且發現Web服務。
綜合起來,一個Web服務就是和現實世界交換SOAP文檔的一個實體,使用一些URI定位,使用WSDL文檔描述並且可以使用UDDI注冊來列出並發現。
一個真實的示例
無數類型的文檔可以被發送到Web服務並來源於Web服務。它可以是一個鋼廠中的周期的溫度報道,它可以是一個地方政府定義的退稅請求,或者它可以是一個從一個軟件組件到另一個組件的RPC調用的文檔風格表現。同樣的情況也發生在文檔交換方案中。你可以設想單向的消息或者請求-響應消息傳送,這裏麵都需要跟隨一個響應文檔的請求文檔。 Web服務大部分當前的用法遵循XML模式上的遠程過程調用。這就是為什麼開發者可以很容易轉到開發Web服務,而不要對現有的應用程序做重大的修改,或者之需要付出最小的努力就能創建用於Web服務的客戶端。Web服務框架經常可以隱藏底層體係結構的複雜性。他們通常提供了用於從語言到WSDL和從WSDL到語言生成的工具。展示象Web服務這樣的語言結構比手工處理XML文檔快得多並且容易的多。現在,Web服務經常用作一個集成工具,讓開發者和係統設計師互連不同的應用程序。
即使本文中的Web服務和它的客戶端遵循XML模式上的遠程過程調用,但是Web服務的應用範圍是非常寬廣的。近期,有許多基於鬆散耦合的純文檔交換模式實現。
一個簡單的聊天服務器
在本文中,我試圖創建一個比著名的股票行情服務更具挑戰的應用程序,但是仍然簡單易讀。它是一個聊天服務器應用程序。聊天服務器的功能是非常簡單的客戶端或者發送新消息並讀取它們。
這個聊天服務器實現是與WASP和Web服務完全互不相關的。它可以成功地被編譯並且用於任何其他的Java環境。這個聊天服務器還描述預存在的業務邏輯。請查看代碼來領會。你可以在這裏下載用於聊天實現的源代碼(而不是Web服務,那個還沒有寫)。
設計聊天服務器
聊天服務器的全部的實現被分割到好幾個類中。接口定義在程序包com.systinet.simplechat.server.iface中。它由三個類組成;聊天服務器的接口類IChatService.java和用於聊天消息的表現兩個結構和participants-ChatMessage.java和ChatPerson.java。
聊天服務器的實現在程序包com.systinet.simplechat.server.impl中。它把簡單的接口的實現從後端業務邏輯中分離出來。我使用了適配器設計模式,那就是說,到ChatService.java的調用被委托給一個後端處理機。業務邏輯是相當簡單的。它是在一個集合中保存消息的SimpleBackendImpl.java類的單一實例。
初看起來,置配器/後端實現看起來對於用於一個簡單的教程太複雜了。然而,即使複雜的現有的業務邏輯可以被重使用來變成一個沒有任何改變它的代碼的需要的Web服務。這是一個常見的現實的使用案例。即使應用程序沒有使用原來的適配器模式,編寫一個象ChatService這樣的包裝類,不需要重寫原始的後端程序邏輯。然而,後端可以使用JDBC和一個關係數據庫來實現,否則作為一個EJB,甚至調用外部非Java應用程序的本地方法。可能發生的事是無窮盡的。適配器模式隻允許你很快地觸發新的後端邏輯。
把一個聊天服務器轉為一個Web服務
現在,這個聊天服務器隻是一個Java實現。它還不是SOAP。它隻是一個用於運行在相同JVM上的客戶端的可工作的聊天服務器。下一步就是生成聊天服務器發言SOAP並且創建一個描述它的WSDL文檔。
這個示例使用Systinet的Web Applications and Services Platform(WASP)軟件來創建Web服務應用程序。WASP軟件是平台無關的並且工作在幾乎任何Java環境中。這個平台提供了兩個不同的部署情況:編程部署和聲明部署。在這兩種情況下,取得部署的是簡單的舊的Java對象。編程部署(也稱運行時間發布)發生在一個應用的運行時間並且能動態的部署應用程序為Web服務。你隻要在你的應用程序中逐步開始WASP,並且使用到WASP應用編程接口的調用注冊它的對象。換句話說,你事實上把WASP嵌入到你的應用程序。聲明部署意味著把你的應用程序包裝到一個部署程序包並且把這個發布到一個WASP的運行實例中。為了簡單和便於訪問起見,我們使用運行時間發布方法。