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

EJB 客戶端實戰:RMI-IIOP 與 CORBA 兩種調用模式完整代碼詳解

     編輯:Java 相關知識

從代碼看 EJB 遠程調用的兩種面孔

EJB 規範定義了標準的遠程調用協議 RMI-IIOP,但允許客戶端以兩種截然不同的 API 風格接入:標準的 javax.naming + javax.rmi (RMI-IIOP 風格) 與標準的 org.omg.CORBA + org.omg.CosNaming (CORBA 風格)。本文通過完整的 HelloWorld 實例,對比展示兩種模式的代碼結構、關鍵 API 及事務控制差異。

模式一:RMI-IIOP 風格客戶端(標準 J2EE 風格)

這是最常見、最符合 J2EE 規範的寫法,適用於純 Java 客戶端調用任意兼容 EJB 容器。

package com.wiley.compBooks.roman.corba.helloworld;

import javax.ejb.*;
import javax.naming.*;
import javax.rmi.*;
import java.util.Properties;
import javax.transaction.UserTransaction;

/**
 * 調用無狀態 Session Bean 的標準 RMI-IIOP 客戶端示例
 */
public class RMIClient {
    public static void main(String[] args) {
        try {
            // 1. 獲取 JNDI 初始化屬性
            Properties props = System.getProperties();
            
            // 2. 創建初始上下文
            Context ctx = new InitialContext(props);
            
            // 3. 查找 Home 接口並進行 narrow 縮窄轉換
            HelloHome home = (HelloHome)
                PortableRemoteObject.narrow(ctx.lookup("HelloHome"), HelloHome.class);
            
            // 4. 查找 JTA UserTransaction 接口
            UserTransaction userTran = (UserTransaction)
                ctx.lookup("javax.transaction.UserTransaction");
            
            // 5. 開啟事務
            userTran.begin();
            
            // 6. 創建 EJB 對象並調用業務方法
            Hello hello = home.create();
            System.out.println(hello.hello());
            
            // 7. 移除 EJB 對象
            hello.remove();
            
            // 8. 提交事務
            userTran.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

關鍵點解析:

  • PortableRemoteObject.narrow():替代 Java 強制轉型,確保跨 ORB 環境下的類型安全。
  • javax.transaction.UserTransaction:標準 JTA 客戶端事務 API,容器無關。
  • JNDI 名稱 "HelloHome" 為邏輯名,部署時映射到具體容器命名空間。

模式二:CORBA 風格客戶端(基於 CORBA EJB 服務端)

當 EJB 部署在基於 CORBA 架構的容器(如早期 WebLogic, Inprise Application Server)時,可直接使用 CORBA API 進行更底層的控制。

package com.wiley.compBooks.roman.corba.helloworld;

import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CosTransactions.*;
import org.omg.CORBA.ORB;

public class CORBAClient {
    public static void main(String[] args) throws Exception {
        // 1. 初始化 ORB(此處使用廠商專有方式獲取)
        ORB orb = com.inprise.ejb.Global.orb(); 
        
        // 2. 獲取命名上下文
        NamingContext context = NamingContextHelper.narrow(
            orb.resolve_initial_references("NameService"));
        
        // 3. 通過 COS Naming 查找 Home 對象
        NameComponent[] names = { new NameComponent("HelloHome", "") };
        HelloHome helloHome = HelloHomeHelper.narrow(context.resolve(names));
        
        // 4. 獲取 OTS (Object Transaction Service) Current 接口控制事務
        Current currentTX = CurrentHelper.narrow(
            orb.resolve_initial_references("TransactionCurrent"));
        
        // 5. 開啟事務
        currentTX.begin();
        
        // 6. 創建 EJB 對象並調用業務方法
        Hello hello = helloHome.create();
        System.out.println(hello.hello());
        
        // 7. 移除 EJB 對象
        hello.remove();
        
        // 8. 提交事務 (true 表示報告啟發式決策)
        currentTX.commit(true);
    }
}

關鍵差異對比:

維度RMI-IIOP 客戶端CORBA 客戶端
命名服務JNDI (InitialContext)COS Naming (NamingContext)
對象縮窄PortableRemoteObject.narrow()XXXHelper.narrow() (IDL 生成)
事務控制JTA UserTransactionOTS Current
ORB 管理隱式 (由 RMI 運行時管理)顯式 (ORB.init() 或廠商 API)
可移植性高 (標準 J2EE)低 (依賴容器 CORBA 實現)

部署與運行提示

  1. Stub/Skeleton 生成:兩種模式均需預先生成 Stub/Skeleton 類。RMI-IIOP 使用 rmic -iiop,CORBA 使用 idlj 處理 IDL 文件。
  2. 類路徑配置:客戶端需包含 HelloHome, Hello 等接口類、Stub 類及容器客戶端 JAR 包。
  3. 屬性文件:RMI-IIOP 客戶端通常需 jndi.properties 指定 java.naming.factory.initial 及 provider.url (IIOP 端點)。

總結

RMI-IIOP 風格是構建可移植 J2EE 應用的首選;CORBA 風格則適用於需要深度整合現有 CORBA 資產、或利用容器特有 CORBA 服務(如高級負載均衡、特定攔截器)的場景。理解雙模式代碼結構,有助於在遷移、整合項目中做出正確的技術選型。

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