• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • J2EE從零開始之EJB(2)

    發表于:2007-04-29來源:作者:點擊數: 標簽:ejb開始j2ee
    本節演示如何 開發 和 測試 一個無狀態會話EJB。本節提供的實例演示了一個簡化的股票交易操作,示意圖如圖4-4所示。 從上圖看出,無狀態EJB:TraderBean由多個客戶端共享使用,不保存客戶端的狀態。 通過這個實例,讀者可以知道: ·如何定義無狀態EJB的主接
    本節演示如何開發測試一個無狀態會話EJB。本節提供的實例演示了一個簡化的股票交易操作,示意圖如圖4-4所示。
       從上圖看出,無狀態EJB:TraderBean由多個客戶端共享使用,不保存客戶端的狀態。
       通過這個實例,讀者可以知道:
       ·如何定義無狀態EJB的主接口、遠程接口和如何編寫EJB實現類
       ·如何使用對象作為遠程方法的返回值
       ·如何在ejb-jar.xml中定義和在無狀態EJB中通過會話上下文使用環境參數
       本例中包括服務器端程序和客戶端程序,把服務器端程序放在C:\bea\wlserver6.0\config\mydomain\applications\DefaultWebApp_myserver\WEB-INF\classes目錄下,如果沒有classes這個目錄,請手工創建;把客戶端程序放在一個目錄下,這里用C:\bea\wlserver6.0\config\mydomain\clientclasses。如果沒有子目錄clientclasses,則創建它,如果不創建這兩個目錄,本實例將不能正常運行。

    4.3.2 編寫源文件

      這個例子的代碼包括兩個接口、三個類。我們把它們都定義在包examples.ejb.basic.statelessSession中,因此創建了目錄:
       C:\work\examples\ejb\basic\statelessSession
       該實例使用到的文件列表和描述如表4-1所示。
              表4-1 無狀態會話EJB文件列表
       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       名稱      類名      文件名       所在包
       ─────────────────────────────────
       主接口     TraderHome   TraderHome.java  examples.ejb.basic.statelessSession
       遠程接口    Trader     Trader.java    examples.ejb.basic.statelessSession
       遠程方法返回類 TraderResult  TraderResult.java examples.ejb.basic.statelessSession
       bean實現類            TraderBean.java examples.ejb.basic.statelessSession
       客戶端測試類  Client     Client.java    examples.ejb.basic.statelessSession
       bean說明文件          ejb-jar.xml
       bean部署文件          weblogic-ejb-jar.xml
       ─────────────────────────────────
       1.主接口程序
       無狀態Session Bean的主接口定義比較簡單。它本身不需維持自身的狀態,所以不需要個性化的創建方法,即create方法是不帶有參數的。
       無狀態Session Bean的主接口定義比較簡單。它本身不需維持自身的狀態,所以不需要個性化的創建方法,即create方法是不帶有參數的。
       編輯TraderHome.java并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(或從附帶光盤的src\examples\ejb\basic\statelessSession目錄拷貝),其源文件如下:

      //定義本接口在包examples.ejb.basic.statelessSession中
       package examples.ejb.basic.statelessSession;
       //本接口用到的其他
       //javax.ejb.EJBHome定義了EJB主接口,被用戶定義的主接口繼承
       import java.rmi.RemoteException;
       import javax.ejb.CreateException;
       import javax.ejb.EJBHome;

      /**
       * 這是TradeBean的主接口定義,這個接口是被EJB容器產生的類TraderBeanC實現的。
       * 在這里只需定義EJB創建的方法,這些方法要和EJBean中的"ejbCreate"方法對應。
       */
       //EJBean主接口必須繼承javax.ejb.EJBHome接口
       public interface TraderHome extends EJBHome {

      /**
       * 這個方法和"TraderBean.java"中定義的的Bean的"ejbCreate"方法相對應
       * 這兩個方法的參數應該相同。當客戶端調用"TraderHome.create()"方法時,EJB容器
       * 會找到EJBean的實例,并調用它的"ejbCreate()"方法。
       *
       * @返回 遠程對象Trader
       * @異常 RemoteException 當系統通訊發生故障時拋出
       * @異常 CreateException 創建EJBean錯誤時拋出
       * @參看 examples.ejb.basic.statelessSession.TraderBean
       */
       Trader create() throws CreateException, RemoteException;
       }

      2. 遠程接口程序
       在遠程接口中定義業務邏輯方法,這個接口中定義了兩個業務邏輯方法,buy和sell,分別對應股票交易中的買進和賣出。
       編輯文件Trader.java并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(或從附帶光盤的src\examples\ejb\basic\statelessSession目錄拷貝),其源文件如下:

      //文件名:Trader.java
       //定義本接口在包examples.ejb.basic.statelessSession中
       package examples.ejb.basic.statelessSession;
       //本接口用到的其他類
       //javax.ejb.*中定義了實現EJBean的接口。
       import java.rmi.RemoteException;
       import javax.ejb.EJBObject;

      /**
       * 這是TradeBean的遠程接口定義。遠程接口中定義了客戶端能遠程調用EJBean的方法。這些方法除了
       * 要拋出異常java.rmi.RemoteException之外,和EJBean中的定義是一致的。但并不是EJBean來實
       * 現這個接口,而是由容器自動產生的類TraderBeanE實現的。
       */
       //這個接口必須繼承javax.ejb.EJBObject接口
       public interface Trader extends EJBObject {

       /**
        * 遠程方法:購買指定股票類別、數量的股票。
        *
        * @參數 stockSymbol 股票代碼
        * @參數 shares 購買股票的數量
        * @返回 TradeResult 交易結果對象
        * @異常 RemoteException 當系統通訊發生故障時拋出
        */
       public TradeResult buy (String stockSymbol, int shares)
        throws RemoteException;

       /**
        * 遠程方法:出售指定股票類別、數量的股票。
        *
        * @參數 stockSymbol 股票代碼
        * @參數 shares 出售股票的數量
        * @返回 TradeResult Trade Result
        * @異常 RemoteException 當系統通訊發生故障時拋出
        */
        public TradeResult sell (String stockSymbol, int shares)
         throws RemoteException;
       }

      3. 遠程方法返回結果類
       這個例子演示了在EJB遠程調用方法返回中如何使用對象。在遠程方法sell和buy定義中我們盾到返回值是一個TradeResult對象。對于這樣的類定義,需要注意的是它必須實現java.io.Serializable接口。這是因為遠程方法返回對象要在不同主機(或虛擬機)之間的網絡流之間傳遞,而在流之間傳遞的對象必須要實現Serializable接口,否則會拋出異常。
       編輯文件TradeResult.java并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(或從附帶光盤的src\examples\ejb\basic\statelessSession目錄下拷貝),其源文件如下:

      //定義本類在包examples.ejb.basic.statelessSession
       package examples.ejb.basic.statelessSession;

      import java.io.Serializable;

      /**
       * 這個類代表買/賣股票的結果
       */
       //遠程方法使用的類必須實現Serializable接口
       public final class TradeResult implements Serializable {

      // 真實的買賣數量
       private final int numberTraded;
       //股票代號
       private final String stockSymbol;
       //構造交易結果對象
       public TradeResult(int nt, String ss) {
        numberTraded = nt;
        stockSymbol = ss;
       }
       //get方法
       public int getNumberTraded() { return numberTraded; }
       public String getStockSymbol() { return stockSymbol; }
       }

      4. Bean實現類
       Bean類用來實現在遠程接口中定義的業務邏輯方法,這里簡單實現了buy和sell方法。
       這個例子演了EJB如何獵取環境參數的方法。作為無狀態會話Bean來說,雖然不能在客戶端創建的時候指定參數,但可以通過在部署描述符中定義環境參數來給無狀態Bean賦值。在實現時可以用下下文InitialContext的lookup()方法獵取參數值。
       同時在這個例子中也演示了怎樣使用用戶定義的異常。
       編輯文件TraderBean.java并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(或從附帶光盤的src\examples\ejb\basic\statelessSession目錄拷貝),其源文件如下:

      //定義本類在包examples.ejb.basic.statelessSession中
       package examples.ejb.basic.statelessSession;
       //本類用到的其他類。javax.ejb.*是開發EJB應用需要的類庫。javax.naming.*是實現JNDI服務需要的類庫。
       import javax.ejb.CreateException;
       import javax.ejb.SessionBean;
       import javax.ejb.SessionContext;
       import javax.naming.InitialContext;
       import javax.naming.NamingException;

      /**
       * TraderBean 是一個無狀態EJB,它演示了如何:
       * 在會話過程中不保持用戶的狀態
       * 用戶定義異常
       */
       //這個類是會話Bean,因此必須實現接口 SessionBean
       public class TraderBean implements SessionBean {
        //設置是否打印控制臺
        private static final boolean VERBOSE = true;
        //聲明會話上下文變量
        private SessionContext ctx;
        //設計交易限制變量
        private int tradeLimit;

       // 使用日志記錄
        private void log(String s) {
        if (VERBOSE) System.out.println(s);
       }

       /**
       * 這是本類必須實現的方法,在本例中沒有用到
       *
       */
       public void ejbActivate() {
        log("ejbActivate called");
       }

      /**
       * 這是本類必須實現的方法,在本例中沒有用到
       *
       */
       public void ejbRemove() {
        log("ejbRemove called");
       }

      /**
       * 這是本類必須實現的方法,在本例中沒有用到
       *
       */
       public void ejbPassivate() {
        log("ejbPassivate called");
       }

      /**
       * 設置會話上下文變量
       *
       * @參數 ctx SessionContext Context for session
       */
       public void setSessionContext(SessionContext ctx) {
        log("setSessionContext called");
        this.ctx = ctx;
       }

      /**
       * 這個方法與"TraderHome.java"中定義的主接口中的"create"方法相對應
       * 兩個方法的參數相同。當客戶端調用主接口的"TraderHome.create()"方法時,
       * 容器會分配一個EJBean實例,并調用它的"ejbCreate()"方法。
       *
       * @異常 javax.ejb.CreateException 創建EJBean出錯時拋出的異常
       * @參看 examples.ejb.basic.statefulSession.Trader
       */
       public void ejbCreate () throws CreateException {
        log("ejbCreate called");

       try {
         //初始化JNDI名稱服務上下文
         InitialContext ic = new InitialContext();
         //從環境變量上下文中查找交易限制參數值
         Integer tl = (Integer) ic.lookup("java:/comp/env/tradeLimit");

         tradeLimit = tl.intValue();
        } catch (NamingException ne) {
        throw new CreateException("Failed to find environment value "+ne);
       }
       }

      /**
       * 購買指定用戶和股票類別、數量的股票。
       *
       * @參數 stockSymbol 股票代碼
       * @參數 shares 購買股票的數量
       * @返回 TradeResult 交易結果對象
       */
       public TradeResult buy(String stockSymbol, int shares) {

      if (shares > tradeLimit) {
       log("Attempt to buy "+shares+" is greater than limit of "+tradeLimit);
       shares = tradeLimit;
       }

      log("Buying "+shares+" shares of "+stockSymbol);
       //返回交易結果對象
       return new TradeResult(shares, stockSymbol);
       }

      /**
       * 出售指定用戶和股票類別、數量的股票。
       *
       * @參數 stockSymbol 股票代碼
       * @參數 shares 出售股票的數量
       * @返回 TradeResult Trade Result
       */
       public TradeResult sell(String stockSymbol, int shares) {

      if (shares > tradeLimit) {
       log("Attempt to sell "+shares+" is greater than limit of "+tradeLimit);
       shares = tradeLimit;
       }

      log("Selling "+shares+" shares of "+stockSymbol);
       //返回交易結果對象
       return new TradeResult(shares, stockSymbol);
       }
       }

      5. 編輯部署文件
       會話EJB使用兩個部署說明文件,ejb-jar.xml用來描述EJB的結構、類型、環境參數等。weblogic-ejb-jar.xml用來描述與部署相關的信息。
       編輯ejb-jar.xml和weblogic-ejb-jar.xml并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(或從附帶光盤的src\examples\ejb\basic\statelessSession目錄拷貝),其源文件如下:

      <?xml version="1.0"?>
       <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>

      <ejb-jar>
       <small-icon>images/green-cube.gif</small-icon>
       <enterprise-beans>
       <session>
       <small-icon>images/orange-cube.gif</small-icon>
       <ejb-name>statelessSession</ejb-name>
       <home>examples.ejb.basic.statelessSession.TraderHome</home>
       <remote>examples.ejb.basic.statelessSession.Trader</remote>
       <ejb-class>examples.ejb.basic.statelessSession.TraderBean</ejb-class>
       <session-type>Stateless</session-type>
       <transaction-type>Container</transaction-type>
       <env-entry>
       <env-entry-name>WEBL</env-entry-name>
       <env-entry-type>java.lang.Double </env-entry-type>
       <env-entry-value>10.0</env-entry-value>
       </env-entry>
       <env-entry>
       <env-entry-name>INTL</env-entry-name>
       <env-entry-type>java.lang.Double </env-entry-type>
       <env-entry-value>15.0</env-entry-value>
       </env-entry>
       <env-entry>
       <env-entry-name>tradeLimit</env-entry-name>
       <env-entry-type>java.lang.Integer </env-entry-type>
       <env-entry-value>500</env-entry-value>
       </env-entry>
       </session>
       </enterprise-beans>
       <assembly-descriptor>
       <container-transaction>
       <method>
       <ejb-name>statelessSession</ejb-name>
       <method-intf>Remote</method-intf>
       <method-name>*</method-name>
       </method>
       <trans-attribute>Required</trans-attribute>
       </container-transaction>
       </assembly-descriptor>
       </ejb-jar>

      ejb-jar.xml可以分為以下幾個部分:
       <ejb-name>:定義這個EJB的名字,這里命名為statelessSession。
       <home>:指定主接口,這里指定為examples.ejb.basic.statelessSession.TraderHome。
       <remote>:指定遠程接口,這里指定為examples.ejb.basic.statelessSession.Trader。
       <ejb-class>:指定EJB類,這里指定為examples.ejb.basic.statelessSession.TraderBean。
       <session-type>:定義會話類型,這里定義為Stateless,無狀態。
       <env-entry>:定義環境參數名和值,可以通過EJB類中上下文對象的lookup方法獲取。
       weblogic-ejb-jar.xml的源文件如下:

      <?xml version="1.0"?>

      <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>

      <weblogic-ejb-jar>
       <weblogic-enterprise-bean>
       <ejb-name>statelessSession</ejb-name>
       <caching-descriptor>
       <max-beans-in-free-pool>100</max-beans-in-free-pool>
       </caching-descriptor>
       <jndi-name>statelessSession.TraderHome</jndi-name>
       </weblogic-enterprise-bean>
       </weblogic-ejb-jar>

      weblogic-ejb-jar.xml文件主要定義了與EJB部署相關的信息,主要有:
       <ejb-name>:EJB的名字,這里是statelessSession
       <caching-descriptor>:EJB緩沖池描述,這里定義了自由池的EJB實例數。
       注意 Weblogic Server中,為了提高無狀態EJB的訪問效率,采用了自由池的技術,所謂自由池技術就是在自由池中為同一個無狀態EJB類實例化多個對象(指定最大數),來處理多用戶折情況,提高效率,而在客戶端看來,卻是透明的,和訪問同一個實例進行的處理方法一樣。
       6. 客戶端測試程序代碼編寫
       編輯client.java文件并保存到C:\work\src\examples\ejb\basic\statelessSession目錄下(也可以直接從配套光盤的類似路徑下拷貝),其源文件的代碼如下:

      //定義本類在包examples.ejb.basic.statelessSession中
       package examples.ejb.basic.statelessSession;
       //本類用到的其他類
       import java.rmi.RemoteException;
       import java.util.Properties;

      import javax.ejb.CreateException;
       import javax.ejb.RemoveException;
       import javax.naming.Context;
       import javax.naming.InitialContext;
       import javax.naming.NamingException;
       import javax.rmi.PortableRemoteObject;

      /**
       * 這個類演示了如何調用一個會話,并進行如下操作:
       * 創建一個Trader遠程對象
       * 使用Trader遠程對象購買一定數量的股票
       * 出售一定數量的股票
       * 清除Trader遠程對象
       */

      public class Client {
       //定義JNDI服務中EJB的名稱
       private static final String JNDI_NAME = "statelessSession.TraderHome";
       //聲明應用服務器的URL變量
       private String url;
       //聲明主接口變量
       private TraderHome home;

      public Client(String url)
       throws NamingException
       {

      this.url = url;
       //尋找主接口
       home = lookupHome();
       }

      /**
       * 在命令行運行這個實例:
       * java examples.ejb.basic.statefulSession.Client "t3://localhost:7001"
       * 參數是可選的
       */
       public static void main(String[] args) throws Exception {

      log("\nBeginning statelessSession.Client...\n");
       //聲明應用服務器地址變量
       String url = "t3://localhost:7001";
       // Parse the argument list
       if (args.length != 1) {
       //打印用法提示
       System.out.println("Usage: java examples.ejb.basic.statelessSession.Client t3://hostname:port");
       return;
       } else {
       url = args[0];
       }

      Client client = null;
       try {
       //創建客戶端實例
       client = new Client(url);
       } catch (NamingException ne) {
       System.exit(1);
       }

      try {
       //調用測試方法
       client.example();
       } catch (Exception e) {
       //異常處理
       log("There was an exception while creating and using the Trader.");
       log("This indicates that there was a problem communicating with the server: "+e);
       }

      log("\nEnd statelessSession.Client...\n");
       }

      /**
       * 運行實例
       */
       public void example()
       throws CreateException, RemoteException, RemoveException
       {

       // 創建遠程對象
       log("Creating a trader");
       Trader trader = (Trader) narrow(home.create(), Trader.class);

      String [] stocks = {"BEAS", "MSFT", "AMZN", "HWP" };

      // 執行一系列購買操作
       for (int i=0; i<stocks.length; i++) {
       int shares = (i+1) * 100;
       log("Buying "+shares+" shares of "+stocks[i]+".");
       trader.buy(stocks[i], shares);
       }

      // 執行一系列出售操作
       for (int i=0; i<stocks.length; i++) {
       int shares = (i+1) * 100;
       log("Selling "+shares+" shares of "+stocks[i]+".");
       trader.sell(stocks[i], shares);
       }

      // 清除遠程對象
       log("Removing the trader");
       trader.remove();

      }

      /**
       * 使用RMI/IIOP的narrow方法
       */
       private Object narrow(Object ref, Class c) {
       return PortableRemoteObject.narrow(ref, c);
       }

      /**
       * 在JNDI樹中尋找EJB主接口
       */
       private TraderHome lookupHome()
       throws NamingException
       {
       // 使用JNDI尋找EJB
       Context ctx = getInitialContext();

       try {
       Object home = ctx.lookup(JNDI_NAME);
       return (TraderHome) narrow(home, TraderHome.class);
       } catch (NamingException ne) {
       //異常處理
       log("The client was unable to lookup the EJBHome. Please make sure ");
       log("that you have deployed the ejb with the JNDI name "+JNDI_NAME+" on the WebLogic server at "+url);
       throw ne;
       }
       }

      /**
       * 使用屬性對象獲取JNDI服務上下文
       */
       private Context getInitialContext() throws NamingException {

       try {
       // 聲明屬性對象
       Properties h = new Properties();
       h.put(Context.INITIAL_CONTEXT_FACTORY,
       "weblogic.jndi.WLInitialContextFactory");
       h.put(Context.PROVIDER_URL, url);
       //返回的特定屬性的上下文對象
       return new InitialContext(h);
       } catch (NamingException ne) {
       //異常處理
       log("We were unable to get a connection to the WebLogic server at "+url);
       log("Please make sure that the server is running.");
       throw ne;
       }
       }

      /**
       * 可以使用jndi.properties屬性文件
       *
       */
       // private static Context getInitialContext()
       // throws NamingException
       // {
       // return new InitialContext();
       // }
       //打印控制臺輸出
       private static void log(String s) {
       System.out.println(s);
       }
       }

    4.3.3 編譯與打包

      1. 編譯代碼
       ·打開命令窗口,進入c:\work\src\examples\ebj\basic\statelessSession目錄。
       ·運行設置環境變量命令腳本setEnv.cmd:
       c:\work\src\examples\ejb\basic\statelessSession>c:\work\setEnv
       setEnv.cmd在附帶光盤的work目錄下,可以直接把它拷貝到c:\work\目錄。
       ·編譯好的代碼要放在build目錄下,因此在編譯之前要創建build目錄:
       c:\work\src\examples\ebj\basic\statelessSession、>md build
       ·打開命令行窗口,進行c:\work\src\examples\ebj\basic\statelessSession目錄,運行:
       c:\work\src\examples\ebj\basic\statelessSession>javac -d build Trader.java TraderHome.java TradeResult.java TraderBean.java
       其中 -d build 表示編譯后的字節碼文件放在build子目錄下。
       這個命令執行的結果是在build目錄下生成examples目錄。
       2. 打包
       打包之前,拷貝必要的文件到規定的目錄。繼續使用上面的步驟及命令,運行如下命令:
       c:\work\src\examples\ejb\basic\statelessSession>mkdir build
       c:\work\src\examples\ejb\basic\statelessSession>mkdir build\META-INF
       c:\work\src\examples\ejb\basic\statelessSession>mkdir build\images
       c:\work\src\examples\ejb\basic\statelessSession>copy *.xml build\META-INF
       c:\work\src\examples\ejb\basic\statelessSession>copy *.gif build\images
       用jar命令打包,包括三部分文件,分別在build目錄的三個子目錄下:
       ·META-INF:xml部署文件
       ·examples:類文件
       ·images:圖像文件
       ·在命令窗口中繼續運行如下命令:
       c:\work\src\examples\ejb\basic\statelessSession>cd build
       c:\work\src\examples\ejb\basic\statelessSession>jar cv0f std_ejb_basic_statelessSession.jar META-INF examples images
       這個命令執行的結果是在build目錄下生成std_ejb_basic_statelessSession.jar文件。
       3.編譯容器代碼
       這是與應用程序服務器平臺相關的一個操作。WebLogic Server 6.0自帶了一個容器代碼%


    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    ...

    熱門標簽

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>