首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Web 服務客戶端開發指南:JAX-RPC、JNDI、靜態存根、動態代理與 DII 全解析

     編輯:Java 相關知識

Web 服務互操作性源於 WS-I 組織推動的標準化。Java 客戶端可訪問任何遵循規範的 Web 服務(不限 Java 實現)。本文系統介紹 Java 客戶端在 J2SE(非受管)與 J2EE(容器受管)環境下的服務查找與訪問機制,涵蓋 JAX-RPC ServiceFactory、JNDI 查找、靜態存根、動態代理、動態調用接口 (DII) 及動態發現調用 (DDI) 五大核心模式。

服務角色與規範基礎

  • 提供者:以 WSDL 描述服務,發布至 UDDI。
  • 請求者 (客戶端):查找 UDDI,綁定服務,調用操作。

核心規範:

  • JSR 101 (JAX-RPC):定義 Java↔XML 映射、WSDL↔Java 映射、編程模型與 API。
  • JSR 109:定義 J2EE 環境下 Web 服務編程模型、部署模型,客戶端模型遵循 JAX-RPC。

兩者均為 J2EE 1.4 組成部分。

服務查找:兩種環境,兩種方式

非受管客戶端 (J2SE):JAX-RPC ServiceFactory

標準查找方式,廠商無關,可移植。步驟:

  1. (可選) 指定 WSDL URL。
  2. 構造服務 QName (命名空間 + 服務名)。
  3. 調用 ServiceFactory.newInstance().createService(wsdlURL, serviceQName)。
String wsdlURL = "https://localhost:6080/HelloWebService/services/Hello?wsdl";
String namespace = "https://Hello.com";
String serviceName = "HelloWebService";
QName serviceQN = new QName(namespace, serviceName);

ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new URL(wsdlURL), serviceQN); // wsdlURL 可選

廠商專屬 ServiceFactory 雖簡化代碼但犧牲可移植性。

受管客戶端 (J2EE):JNDI 查找

JSR 109 強制規定標準方式。客戶端打包為 EAR,含部署描述符聲明服務引用。步驟:

  1. 實例化 InitialContext。
  2. 查找邏輯名:java:comp/env/service/HelloService (建議統一置於 service 子上下文)。
Context ic = new InitialContext();
Service service = (Service) ic.lookup("java:comp/env/service/HelloService");
// 或直接轉型為服務專屬介面
HelloServiceInterface svc = (HelloServiceInterface) ic.lookup("java:comp/env/service/HelloService");

容器保證綁定符合 JAX-RPC Service 實現。

服務訪問:三大模式

獲得 Service 實例後,可獲取三種調用代理:

1. 靜態存根

  • 預先生成:WSDL→Java 映射工具 (如 Axis Java2WSDL、IBM WSDL2Client) 生成 SEI、存根、序列化器等構件。
  • 存根實現 SEI,綁定特定協議/傳輸 (SOAP)。
  • 調用極簡:Hello stub = (Hello) service.getHello(); stub.getGreeting("Jane");
  • 缺點:需開發期 WSDL、運行映射工具、存根非可移植、不宜打包分發。

2. 動態代理

  • 運行時由 Service.getPort(portQName, SEI.class) 生成實現 SEI 的代理類。
  • 代碼:Hello proxy = service.getPort(portQN, Hello.class); proxy.getGreeting("Jane");
  • 優勢:可移植、廠商無關、標準化。
  • 前提:仍需開發期 WSDL 運行映射工具生成 SEI。

3. 動態調用接口 (DII)

  • 無需開發期 WSDL,完全運行時配置。
  • 步驟:
    1. 獲取 Service (非受管僅傳服務名 createService(serviceQName),受管 JNDI 查找)。
    2. Call call = service.createCall();
    3. 配置 Call:操作名、端口類型、目標端點地址、編碼風格、參數/返回類型。
    4. call.invoke(inputParams) 執行調用。
  • 代碼示例:
    Call call = service.createCall();
    call.setPortTypeName(portQN);
    call.setOperationName(new QName(namespace, "getGreeting"));
    call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, "");
    call.setProperty(Call.OPERATION_STYLE_PROPERTY, "wrapped");
    call.addParameter("param1", XMLType.XSD_STRING, ParameterMode.IN);
    call.setReturnType(XMLType.XSD_STRING);
    String ret = (String) call.invoke(new Object[]{"Jane"});
    
  • 優勢:適應服務變更、無需生成運行時類。
  • 缺點:配置複雜、易出錯。

動態發現與調用 (DDI)

極致靈活:運行時發現 UDDI 服務 → 解析 WSDL 獲取元數據 → DII 調用。步驟:

  1. UDDI Registry Enquiry API 瀏覽註冊中心,獲取 WSDL URL。
  2. UDDI4J API 解析 WSDL,提取命名空間、服務、端口、參數。
  3. DII 調用服務。

選型指南

場景推薦模式
服務穩定、追求簡潔、可接受生成代碼動態代理
服務頻繁變更、無法預知 WSDL、需極致動態DII
舊系統、已有生成工具鏈、性能敏感靜態存根
需動態發現未知服務DDI

結語

Java Web 服務客戶端開發提供了從靜態到完全動態的完整譜系。理解 JAX-RPC ServiceFactory 與 JNDI 查找的環境區別,掌握存根、動態代理、DII 三種訪問模式的適用邊界,是構建健壯、可移植、可維護服務消費者的關鍵。實際項目中,動態代理往往是平衡開發效率與運行時靈活性的最佳選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved