本文展示如何使用簡單技術加上以文檔為中心的方式,帶來有價值的業務服務,無需專有中間件,也無需引入 Web 服務棧的複雜性。靈感源自 REST 架構風格,以及將 XML 移至 HTTP 協議之上的能力。
以簡單天氣服務為例,暴露名為 WeatherQuery 的 Web 方法,返回包含溫度與氣壓的對象。通常做法是用工具暴露方法並生成 WSDL。但事情並不簡單:WSDL 是概括性標準,實際可自由詮釋。.NET 強制用基於文檔的方法,Java 工具卻採用 RPC 方法;還有命名空間混淆、 Schema 包含、工具將 WSDL 切分成獨立部分等問題。技術關注點已偏離實際問題。
更糟的是工具間不一致:不同版本 IIS、WSE 及其 Java 等價產品對自動發布的 WSDL 只能部分兼容。今天湊合能工作,明天若需更複雜的 Web 方法就得拋錨,令人倍感厭煩。
傳統方法有兩個關鍵假設:暴露現有方法調用即足夠;用工具能輕鬆實現 Web 服務訪問。
我們將請求視為包含請求類型與參數的文檔,而非考慮參數與返回類型。把文檔作為業務過程契約描述的一部分。以 WeatherQuery 為例,用 XML 描述請求與返回文檔,定義對應類表示字段。這兩個文檔在 .NET 與 Java 中都易於序列化/反序列化。.NET 用內建 XML 序列化(帶標注),Java 用開源項目 XStream。
Weather 服務僅負責文檔交換,即可用簡單 HTTP 而非 Web 服務。這樣可讓多個文件類型使用同一入口點,帶來更可擴展的方法。
技術棧:XStream 序列化庫 + 任意 Servlet 容器。Servlet 實現 doPost(),使用完整 POST 主體而非名稱/鍵值對。請求傳入時,用 XStream 將 XML 反序列化為命令對象並處理。
僅需 IIS + .NET 內建 XML 序列化。要求 C# 屬性將字段標記為 XML 元素而非屬性。
用 XStream + Apache HttpClient。HttpClient 允許編程方式創建 POST 操作,POST 主體為 XStream 生成的 XML。
僅需 .NET 框架,用內建 WebRequest 與序列化機制。
簡單 POST 命令 XML 的好處:可後續加入更多命令而不改變消息實現。服務器運行期決定能否處理相應 XML。為每類型註冊處理器,避免大量 if/else 或 switch/case。關於 Schema 驗證:運行期驗證帶來虛假安全感,錯誤 XML 仍可能發出,只會拋出 Schema 無效異常。用 XML 映射到類定義,要么得到正確對象,要么對象丟失字段,可拋出帶真實原因的異常,易轉換為清晰 XML 回復。關鍵區別:異常僅在必要信息缺失時拋出,其他可變更。
這種設計允許 XML 加入新元素(對應類新字段),使 API 語義上層更高。經測試後,服務可支持客戶發送舊版本請求文檔。建議在 URL 加入版本號:https://x.com/weather/WeatherQuery/2.0
若需在同一服務器放另一服務處理標準 Web 服務請求,無阻礙。只需 WSDL 指定方法,將 SOAP 編碼交給純 REST 實現的反序列化-執行-序列化代碼。工具選擇:.NET 用 WSE 2.0/3.0,Java 用 Glue、AXIS、JAX-WS 或 J2EE 容器內建適配器。
用 TIBCO Rendezvous 可將請求 XML 發送到隱式異步服務執行。請求不會馬上得到回復,需改變 API 設計:用兩個接口各帶單獨方法替代單一 Facade 方法。消息模式有隊列(請求只接受返回給自己的響應)和多播(發布/訂閱)。甚至可設計持續發送修正信息的隊列,類似 JMS。
我們的生產者/消費者設計以簡單形式交換 XML,無正式 Web 服務的協議檢查。建議:這並非必要。遵循敏捷思維,設計符合持續集成的集成測試,部署前發現不兼容。拋開複雜 WSDL 規範,擁有從提供者與使用者角度斷言服務的單元測試。WSDL 只能運行期提示不兼容,此時恢復不易。Schematron 可作平台無關測試選項。輔助調試與文檔,準備範例文檔與 XSD。靜態提供 XSD 與範例 XML 不錯:API 可通過瀏覽器手動請求。記住,XSD 與範例文檔只是可選,易生成。
法寶:Codehaus XStream,通過 HTTP-POST 而非 GET 與 .NET 進行文檔交換。選用 XStream 意味著消息「規範」存在於 Java/C# 代碼中,而非基於 XML、常讓你面對 WS-* 規範的設計中。傳統 REST 推薦 HTTP-GET 適合編碼命令,尤其結果可被緩存時。我們風格適合通訊場景,嘗試緩存無意義。GET 更優雅、可測試性更強(瀏覽器測試),但缺乏 POST 的多功能性:參數不限名稱/鍵值對,XML 載荷複雜度可任意指定。大型方案中 GET 與 POST 各有其地。
撰文過程中向 XStream 團隊提建議(補丁形式),增強屬性支持以便與 .NET 無縫互操作,已被採納。此法對 Tibco RV 等異步傳輸同樣適用,WS-* 工具基本無支持。文末不肯定是否為 POST-REST (PREST) 或傳統 REST 無緩存無 URL 簡化,亦無新名詞。