免费注册 | 休息吧
中国在线招生
 首 页 新闻资讯  高校招生  职业技校  培训机构  资格认证  高级研修  你问我答  教育博客
         公告:欢迎光临中国在线招生网站,2008全新改版,为各类学校提供更为优质的服务
2008年外教英语夏令营
  您所在的位置:首页  > 培训机构 > IT培训资料 >  5.3 容器管理持久性实体EJB
 

5.3 容器管理持久性实体EJB

2008-8-12 文章来源:培训网  责任编辑:zsol 字体: [ ]
5.3 容器管理持久性实体EJB

5.3.1实例说明

  本示例演示容器管理持久性实体EJB实例的开发过程,内容包括:
  (1)实体EJB主接口、远程接口定义和实现类编写;
  (2)EJB说明文件和部署文件的编写;
  (3)EJB属性与数据表字段映射文件的编写:
  (4)如何定义连接池;
  (5)如何编译EJB程序;
  (6)测试EJB程序。
  示例文件包括:
  AccountHome.java,Account.java,AccountBean.java,ProcessingErrorException.java,Client.java,ejb-jar.xml,weblogic-cmp-rdbms-jar.xml,weblogic-ejb-jar.xml。

5.3.2编写源文件

  1.编写主接口程序
  编辑文件AccountHome.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。AccountHome.java源文件如下: 

  //AccountHome.java
  //定义本接口在包examples.ejb.basic.containerManaged中
  package examples.ejb.basic.containerManaged;
  //本接口用到的其他类
  //javax.ejb.*中定义了实现EJBean的接口。
  import javax.ejb.CreateException;
  import javax.ejb.EJBHome;
  import javax.ejb.FinderException;
  import java.rmi.RemoteException;
  import java.util.Enumeration;

  /**
  * 这是AccontBean的主接口定义,这个接口是被EJB容器产生的类AccontBeanC实现的。
  * 在这里只需定义EJB创建的方法,这些方法要和EJBean中的"ejbCreate"方法对应。
  */

  //EJBean主接口必须继承javax.ejb.EJBHome接口
  public interface AccountHome extends EJBHome {

   /**
   * 这个方法和"AccountBean.java"中定义的的Bean的"ejbCreate"方法相对应
   * 这两个方法的参数应该相同。当客户端调用"TraderHome.create()"方法时,EJB容器
   * 会找到EJBean的实例,并调用它的"ejbCreate()"方法。
   * 对容器管理的ejb,ejbCreate方法返回为null,而bean管理的ejb,返回的是主键类。
   * @参数 accountID String 账号ID
   * @参数 initialBalance double 初始化结算值
   * @参数 type String 账号类型
   * @返回 Account 远程对象
   * @异常 javax.ejb.CreateException
   * 创建bean错误时抛出的异常
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @参看 examples.ejb.basic.containerManaged.AccountBean
   */
   public Account create(String accountId, double initialBalance, String type) 
   throws CreateException, RemoteException;

   /**
   * 根据主键对象,返回账号对象
   *
   * @参数 primaryKey 主键
   * @返回 Account 账号
   * @异常 javax.ejb.FinderException
   * 访问数据库错误抛出的异常
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @参看 examples.ejb.basic.containerManaged.AccountBean
   */
   public Account findByPrimaryKey(String primaryKey) 
   throws FinderException, RemoteException;
 
   /**
   * 找到所有结算值等于balanceEqual的账号
   *
   * @返回 Account 账号
   * @参数 double balanceEqual,给定的结算值
   * @异常 javax.ejb.FinderException
   * 访问数据库错误抛出的异常
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @参看 examples.ejb.basic.containerManaged.AccountBean
   */
   public Account findAccount(double balanceEqual)
   throws FinderException, RemoteException;

   /**
   * 找到所有结算值大于balanceGreaterThan的账号
   *
   * @返回 Enumeration 所有账号枚举
   * @参数 double balanceGreaterThan,给定的结算值
   * @异常 javax.ejb.FinderException
   * 访问数据库错误抛出的异常
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @参看 examples.ejb.basic.containerManaged.AccountBean
   */
   public Enumeration findBigAccounts(double balanceGreaterThan)
   throws FinderException, RemoteException;

   /**
   * 找到所有类型为’null’的EJBeans。
   *
   * @返回 Enumeration 所有账号枚举
   * @异常 javax.ejb.FinderException
   * 访问数据库错误抛出的异常
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @参看 examples.ejb.basic.containerManaged.AccountBean
   */
   public Enumeration findNullAccounts()
   throws FinderException, RemoteException;

  }

  2.编写远程接口程序

  编辑文件Account.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。Account.java源文件如下: 

  //Account.java
  //定义本接口在包examples.ejb.basic.containerManaged中
  package examples.ejb.basic.containerManaged;
  //本接口用到的其他类
  //javax.ejb.*中定义了实现EJBean的接口。
  import java.rmi.RemoteException;
  import javax.ejb.*;

  /**
  * 这是AccontBean的远程接口定义。远程接口中定义了客户端能远程调用EJBean的方法。这些方法除了
  * 要抛出异常java.rmi.RemoteException之外,和EJBean中的定义是一致的。但并不是EJBean来实
  * 现这个接口,而是由容器自动产生的类AccontBeanE实现的。
  */
  //这个接口必须继承javax.ejb.EJBObject接口
  public interface Account extends EJBObject {

   /**
   * 远程方法:存入一定数目的金额
   *
   * @参数 amount 存入金额的数量
   * @返回 double 操作实际结果
   * @异常 RemoteException 当系统通讯发生故障时抛出
   */
   public double deposit(double amount)
   throws RemoteException;

   /**
   * 远程方法:提取一定数目的金额
   *
   * @参数 amount 提取金额的数量
   * @返回 double 操作实际结果
   * @异常 RemoteException 当系统通讯发生故障时抛出
   * @异常 ProcessingErrorException
   * 购买操作出错时抛出的异常
   */
   public double withdraw(double amount)
   throws ProcessingErrorException, RemoteException;

   /**
   * 远程方法:结算
   * @返回 double 结算值
   * @异常 RemoteException 当系统通讯发生故障时抛出
   */
   public double balance() 
   throws RemoteException;

   /**
   * 返回账号类型
   *
   * @返回 String 账号类型
   * @异常 RemoteException 当系统通讯发生故障时抛出
   */
   public String accountType() 
   throws RemoteException;

  }

  3.编写实现类程序

  编辑文件AccountBean.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。AccountBean.java源文件如下: 

  //AccountBean.java
  //定义本接口在包examples.ejb.basic.containerManaged中
  package examples.ejb.basic.containerManaged;
  //本类用到的其他类。javax.ejb.*是开发EJB应用需要的类库。javax.naming.*是实现JNDI服务需要的类库。
  import java.io.Serializable;
  import java.util.Enumeration;
  import java.util.Vector;

  import javax.ejb.CreateException;
  import javax.ejb.DuplicateKeyException;
  import javax.ejb.EJBException;
  import javax.ejb.EntityBean;
  import javax.ejb.EntityContext;
  import javax.ejb.FinderException;
  import javax.ejb.NoSuchEntityException;
  import javax.ejb.ObjectNotFoundException;
  import javax.ejb.RemoveException;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.sql.DataSource;

  /**
  * AccountBean是实体EJB,它演示了:
  * 容器管理的JDBC持续性管理和事务管理;
  * 在这个文件中的代码并没有直接访问数据库;
  * 用户定义的异常;
  * 使用isModified方法,这个方法改变容器管理的字段,通过设置isDirty
  */
  //这个类是实体Bean,必须实现接口 EntityBean
  public class AccountBean implements EntityBean {
   //设置是否打印控制台
   final static boolean VERBOSE = true;
   //声明实体上下文变量
   private EntityContext ctx;
   //声明实体EJB属性变量
   public String accountId; // 这也是主键类
   public double balance;
   public String accountType;
   private transient boolean isDirty; // 决定bean是否谢数据库的标志

   /**
   * 为EJBean设置实体EJB上下文
   * 
   * @参数 ctx EntityContext 
   */
   public void setEntityContext(EntityContext ctx) {
    log("setEntityContext called (" + id() + ")");
    this.ctx = ctx;
   }

   /**
   * 取消实体上下文设置
   * 
   */
   public void unsetEntityContext() {
    log("AccountBean.unsetEntityContext (" + id() + ")");
    this.ctx = null;
   }

   /** 
   * 返回EJBean是否被改变
   *
   * 这个方法必须为public 以使被容器调用
   * 
   * @返回 boolean isDirty
   */
   public boolean isModified() {
    log("isModified(): isDirty = " + (isDirty ? "true" : "false"));
    return isDirty;
   }

   /**
   * 设置EJBean的改变标志
   * 
   * @参数 flag 改变标志
   */
   public void setModified(boolean flag) {
    isDirty = flag;
    log("setModified(): " + id() + (String) (flag ? ": requires saving" 
     : ": saving not required"));
   }

   /**
   * 返回标识这个EJBean的主键
   * 
   * @返回 String 标志
   */
   private String id() {
    return "" + System.identityHashCode(this) + ", PK = " + 
    (String) ((ctx == null) ? "nullctx" 
    : ((ctx.getPrimaryKey() == null ?
    "null" : ctx.getPrimaryKey().toString()))) +
    "; isDirty = " + isDirty;
   }

   /**
   * 这是本类必须实现的方法,在本例中没有用到
   *
   */
   public void ejbActivate() {
    log("AccountBean.ejbActivate (" + id() + ")");
   }

   /**
   * 这是本类必须实现的方法,在本例中没有用到
   *
   */
   public void ejbPassivate() {
    log("AccountBean.ejbPassivate (" + id() + ")");
   }

   /**
   * 这是本类必须实现的方法,在本例中没有用到
   *
   */
   public void ejbLoad() {
    log("AccountBean.ejbLoad (" + id() + ")");
   }

   /**
   * 设置EJBean的改变标记为false
   * 
   */
   public void ejbStore() {
    log("AccountBean.ejbStore (" + id() + ")");

    setModified(false);
   }

   /**
   * 这是本类必须实现的方法,在本例中没有用到
   *
   */
   public void ejbRemove()
   throws RemoveException
   {
    log("AccountBean.ejbRemove (" + id() + ")");
   }
   /**
   * 这个方法和"AccountBean.java"中定义的的Bean的"ejbCreate"方法相对应
   * 这两个方法的参数应该相同。当客户端调用"TraderHome.create()"方法时,EJB容器
   * 会找到EJBean的实例,并调用它的"ejbCreate()"方法。
   * 对容器管理的ejb,ejbCreate方法返回为null,而bean管理的ejb,返回的是主键类。
   * @参数 accountID String 账号ID
   * @参数 initialBalance double 初始化结算值
   * @参数 type String 账号类型
   * @异常 javax.ejb.CreateException
   * 创建bean错误时抛出的异常
   * @参看 examples.ejb.basic.containerManaged.AccountHome
   */
   public String ejbCreate(String accountId, double initialBalance, String type) 
   throws CreateException
   {
    log("AccountBean.ejbCreate( id = " + System.identityHashCode(this) + ", PK = " +
    accountId + ", " + "initial balance = $ " + initialBalance + ")");
    this.accountId = accountId;
    this.balance = initialBalance;
    this.accountType = type;
    return null; // See 9.4.2 of the EJB 1.1 specification
   }

   /**
   * 这是本类必须实现的方法,在本例中没有用到 
   */
   public void ejbPostCreate(String accountId, double initialBalance, String type) 
   {
    log("AccountBean.ejbPostCreate (" + id() + ")");
   }

   // 应用程序定义的方法

   /**
   * 存入一定金额
   *
   * @参数 amount double 数量
   * @返回 double 结算
   */
   public double deposit(double amount)
   {
    log("AccountBean.deposit: Depositing $" + amount + " into ’" + accountId + "’");
    //业务逻辑计算
    balance += amount;
    //设置改变标记
    setModified(true);
    return balance;
   }

   /**
   * 提取一定数量的金额
   *
   * @参数 amount double 数量
   * @返回 double 结算
   * @exception ProcessingErrorException
   * 如果提取的数量大于结算值
   */
   public double withdraw(double amount)
   throws ProcessingErrorException
   {
    log("AccountBean.withdraw: Withdrawing $" + amount + " from ’" + accountId + "’");
    if (amount > balance) {
     //抛出用户定义异常
     throw new ProcessingErrorException("Request to withdraw $" + amount +
     "; is more than balance $" + balance +
     " in account " + accountId);
    }
    //业务逻辑计算
    balance -= amount;
    //设置改变标记
    setModified(true);
    return balance;
   }
   /**
   * 返回当前的结算
   *
   * @返回 double 结算
   */
   public double balance() {
    log("AccountBean.balance (" + id() + ")");

    return balance;
   }
   /**
   * 返回账号类型
   *
   * @返回 String 账号类型
   */
   public String accountType() {
    log("AccountBean.accountType (" + id() + ")");

    return accountType;
   }
   //控制台输出 
   private void log(String s) {
    if (VERBOSE) System.out.println(s);
   }
  }

  4.编写处理异常程序

  用文本编辑器编辑文件ProcessingErrorException.java并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下: 

  //ProcessingErrorException.java
  //定义本类在包examples.ejb.basic.containerManaged 中
  package examples.ejb.basic.containerManaged;

  /**
  * 这是用户定义的异常类
  */
  //用户定义的异常类必须继承Exception
  public class ProcessingErrorException extends Exception {

   /**
   * 获取没有字符串参数的异常
   *
   */
   public ProcessingErrorException() {}

   /**
   * 用特定的字符串构造异常
   *
   * @参数 message Exception 消息
   */
   public ProcessingErrorException(String message) {super(message);}
  }

  5.编写客户端测试程序

  编辑文件Client.java并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下: 

  //Client.java
  //定义本类在包examples.ejb.basic.containerManaged 中
  package examples.ejb.basic.containerManaged;
  //本类用到的其他类
  import java.rmi.RemoteException;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.Vector;
  //本类用到的EJB类
  import javax.ejb.CreateException;
  import javax.ejb.DuplicateKeyException;
  import javax.ejb.FinderException;
  import javax.ejb.ObjectNotFoundException;
  import javax.ejb.RemoveException;
  //本类用到的名称服务类
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.rmi.PortableRemoteObject;
  /**
  * 这个类演示了如何调用一个实体EJB,并进行如下操作:
  * A:创建一个Account远程对象,存入一些钱。然后试图提取超过当前结算的金额。或抛出用户定义的异常,
  * 最后,清除Account远程对象。
  * B:创建一些新的账号,它们有不同的结算值。找到所有计算值大于给定数值的账号。找到结算职为0的账号。
  * 试图查找账号类型为null的账号。最后,删除所有新创立的账号。
  * 这个例子同时演示了怎样在JNDI树查找EJB主接口。
  */
  public class Client {
   //声明变量
   private String url;
   private String accountId;
   private AccountHome home;
   //构造方法
   public Client(String url, String accountId) 
   throws NamingException {

    this.url = url;
    this.accountId = accountId;
    //找找主接口,lookupHome是本例自定义方法。
    home = lookupHome();
   }

   /**
   * 在命令行运行这个实例:
   * java examples.ejb.basic.containerManaged.Client "t3://localhost:7001"
   * 参数是可选的
   * @参数 url URL such as "t3://localhost:7001" of Server
   * @参数 accountID String Account ID to test, default "10020"
   */
   public static void main(String[] args) {
    System.out.println("\nBeginning containerManaged.Client...\n");

    String url = "t3://localhost:7001";
    String accountId = "10020";

    // Parse the argument list 
    switch(args.length) {
     case 2:
      accountId = args[1];
      // fall through
     case 1:
      url = args[0];
      break;
    }

    Client client = null;

    try {
     //实例化本类
     client = new Client(url, accountId);
    } catch (NamingException ne) {
     //异常处理
     log("Unable to look up the beans home: " + ne.getMessage());
     System.exit(1);
    }

    try {
     //运行实例A
     client.runExamplePartA();
     //运行实例B
     client.runExamplePartB();
    } catch (Exception e) {
     //异常处理
     log("There was an exception while creating and using the Accounts.");
     log("This indicates that there was a problem communicating with the server: "+e);
    }

    System.out.println("\nEnd containerManaged.Client...\n");
   }

   /**
   * 执行实例A
   *
   * A: 存入一定数量的金额,并试图提取超过结算的金额,会抛出应用定义的异常
   */
   public void runExamplePartA() {
    log("Starting Part A of the example...\n");
    //初始化变量
    double initialBalance = 3000;
    String accountType = "Savings";
    Account ac = null;
    try {
     //创建账号,createAccount是本类定义的方法
     ac = createAccount(accountId, initialBalance, accountType);
    } catch(DuplicateKeyException dke) {
     //异常处理
     log("An account with id " + accountId + " already exists!");
    } catch(Exception e) {
     //异常处理
     log("Error creating account: " + e.getMessage());
     System.exit(1);
    }
    //设置初始化变量
    int amount = 2000;
    double balance = 0;
    log("\nPart A: Depositing $" + amount );
    try {
     //存入一定数量的金额,deposit是EJB远程方法
     balance = ac.deposit(amount);
     log("Current balance is $" + balance);
    } catch (Exception e) {
    
     log("Error during deposit: "+e.getMessage());
    }

    try {
     log("Attempting to withdraw an amount greater than current balance. Expecting an exception...\n");
     //试图提取超过结算的金额
     balance = ac.withdraw(balance+1);
     log("Error: expected an exception.");
    } catch (ProcessingErrorException pe) {
     //异常处理
     log("Received expected Processing Error:\n" + pe);
    } catch(Exception e) {
     //异常处理
     log("Error during withdraw: "+e.getMessage());
    }

    log("Removing account...\n");
    try {
     //清除账号ac,remove 是远程EJB方法
     ac.remove();
    } catch(Exception e) {
     log("Error removing account: "+e.getMessage());
    }

    log("End Part A of the example...\n");
   }

   /**
   * 例B
   *
   * B: 创建20个不同结算值的新账号。
   * 找到所有结算值大于给定值的账号
   * 结束时,清除账号
   */
   public void runExamplePartB()
   throws CreateException, RemoteException, FinderException,
   RemoveException
   {
    log("Starting Part B of the example...\n");
    //声明变量
    int numBeans = 20;
    //声明远程对象数组
    Account [] accounts = new Account [numBeans];

    // 创建20个有不同初值的账号
    for (int i=0; i<numBeans; i++) {
     // if (Math.IEEEremainder(i, 5) == 0)
     if (i % 5 == 0) {
      // 创建一些账号类型为null的账号。
      // (仅仅是为了下面的查找)
      accounts [i] = findOrCreateAccount("ID: "+i, i * 1000, null);
     } else {
      accounts [i] = findOrCreateAccount("ID: "+i, i * 1000, "Savings");
     }
    }

    // 打印账号结算值
    for (int i=0; i<numBeans; i++) {
     log("Account: :"+accounts[i].getPrimaryKey()+
      " has a balance of "+accounts[i].balance());
    }

    // 查找所有结算大于5000的账号
    findBigAccounts(5000.0);
    // 查找第一个结算值为0的账号
    findAccountWithZeroBalance();
    // 查找所有账号类型为null的账号
    findNullAccounts();

    // 清除所有账号

    log("Removing beans...");
    for (int i=0; i<numBeans; i++) {
     accounts[i].remove();
    }
    log("End Part B of the example...\n");
   }

   /**
   * 列出第一个结算值为0的账号
   * 这个finder方法演示了只返回一个纪录的方法。
   */
   private void findAccountWithZeroBalance() 
   throws FinderException, RemoteException
   {
    log("\nQuerying for an account with zero balance...");
    try {
    // 创建账号远程对象
    Account zeroBalance = (Account)
    PortableRemoteObject.narrow(home.findAccount(0), Account.class);
    // Account zeroBalance = home.findAccount(0);
    log("Account " + zeroBalance.getPrimaryKey() + 
    "; balance is zero");
    } catch(ObjectNotFoundException onfe) {
     //异常处理
     log("No Account was found with a balance of zero");
    }
   }

   /**
   * 列出所有账号类型为null的账号
   * 这个finder方法演示返回账号枚举
   */
   private void findNullAccounts()
   throws RemoteException, FinderException
   {
    log("\nQuerying for accounts with a null account type");
    //账号枚举
    Enumeration enum = home.findNullAccounts();

    if(! enum.hasMoreElements()) {
     log("No accounts were found with a null account type");
    }
    //创建账号远程对象
    while (enum.hasMoreElements()) {
     Account nullAccount= (Account)
     PortableRemoteObject.narrow(enum.nextElement(), Account.class);
     log("Account " + nullAccount.getPrimaryKey() + "; account type is " + nullAccount.accountType());
    }
   }

   /**
   * 列出所有结算大于给定值的账号
   * 这个finder方法演示返回枚举账号
   */
   private void findBigAccounts(double balanceGreaterThan) 
   throws RemoteException, FinderException
   {
    log("\nQuerying for accounts with a balance greater than " +
    balanceGreaterThan + "...");
    //调用主接口创建账号方法findBigAccounts,返回账号枚举
    Enumeration enum = home.findBigAccounts(balanceGreaterThan);

    if(! enum.hasMoreElements()) {
     log("No accounts were found!");
    }

    while (enum.hasMoreElements()) {
     Account bigAccount= (Account)
     //创建远程对象
     PortableRemoteObject.narrow(enum.nextElement(), Account.class);

     log("Account " + bigAccount.getPrimaryKey() + 
     "; balance is $" + bigAccount.balance());
    }
   }

   /**
   * 如果对应id的账号以存在,则返回这个id,否则创建它
   */
   private Account findOrCreateAccount(String id, double balance, String accountType)
   throws CreateException, FinderException, RemoteException
   {
    Account remote = null;
    try {
     remote = (Account)
     PortableRemoteObject.narrow(home.findByPrimaryKey(id),Account.class);
     // remote = home.findByPrimaryKey(id);
    } catch (ObjectNotFoundException onfe) {
     // 账号不存在,创建它
     remote = createAccount(id, balance, accountType);
    }
    return remote;
   }

   
   /**
   * 给定id和结算创建一个新的账号
   */
   private Account createAccount(String id, double balance, String accountType) 
   throws CreateException, RemoteException 
   {
    log ("Creating account " + id + " with a balance of " + 
    balance + " account type " + accountType + "...");
    //创建远程账号对象
    Account ac = (Account) PortableRemoteObject.narrow(
    home.create(id, balance, accountType), Account.class);

    log("Account " + id + " successfully created");

    return ac;
   }

   /**
   * 使用JNDI查找bean的主接口
   */
   private AccountHome lookupHome()
   throws NamingException
   {
    Context ctx = getInitialContext();

    try {
     //查找主接口
     Object home = (AccountHome) ctx.lookup("containerManaged.AccountHome");
     return (AccountHome) PortableRemoteObject.narrow(home, AccountHome.class);

    } catch (NamingException ne) {
     //异常处理
     log("The client was unable to lookup the EJBHome. Please make sure " +
     "that you have deployed the ejb with the JNDI name " + 
     "containerManaged.AccountHome on the WebLogic server at "+url);

     throw ne;
    }
   }

   /**
   * 获取初始化上下文
   */
   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;
    }
   }
   //控制台输出
   private static void log(String s) {
    System.out.println(s);
   }
  }

  6.编写EJB描述文件

  编辑文件ejb-jar.xml并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下: 

  <?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>
   <enterprise-beans>
    <entity>
     <ejb-name>containerManaged</ejb-name>
     <home>examples.ejb.basic.containerManaged.AccountHome</home>
     <remote>examples.ejb.basic.containerManaged.Account</remote>
     <ejb-class>examples.ejb.basic.containerManaged.AccountBean</ejb-class>
     <persistence-type>Container</persistence-type>
     <prim-key-class>java.lang.String</prim-key-class>
     <reentrant>False</reentrant>
     <cmp-field>
      <field-name>accountId</field-name>
     </cmp-field>
      <cmp-field>
     <field-name>balance</field-name>
     </cmp-field>
     <cmp-field>
      <field-name>accountType</field-name>
     </cmp-field>
     <primkey-field>accountId</primkey-field>
    </entity>
   </enterprise-beans>
   <assembly-descriptor>
    <container-transaction>
     <method>
      <ejb-name>containerManaged</ejb-name>
      <method-intf>Remote</method-intf>
      <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
    </container-transaction>
   </assembly-descriptor>
  </ejb-jar>

  7.编写CMP映射文件

  编辑weblogic-cmp-rdbms-jar.xml,保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下: 

  <!DOCTYPE weblogic-rdbms-bean PUBLIC 
’-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB RDBMS Persistence//EN’
’http://www.bea.com/servers/wls510/dtd/weblogic-rdbms-persistence.dtd’>
  <weblogic-rdbms-bean>
   <pool-name>demoPool</pool-name>
   <table-name>ejbAccounts</table-name>
   <attribute-map>
    <object-link>
     <bean-field>accountId</bean-field>
     <dbms-column>id</dbms-column>
    </object-link>
    <object-link>
     <bean-field>balance</bean-field>
     <dbms-column>bal</dbms-column>
    </object-link>
    <object-link>
     <bean-field>accountType</bean-field>
     <dbms-column>type</dbms-column>
    </object-link>
   </attribute-map>
   <finder-list>
    <finder>
     <method-name>findBigAccounts</method-name>
     <method-params>
      <method-param>double</method-param>
     </method-params>
     <finder-query><![CDATA[(> balance $0)]]></finder-query>
    </finder>
    <finder>
     <method-name>findAccount</method-name>
     <method-params>
      <method-param>double</method-param>
     </method-params>
     <finder-query><![CDATA[(= balance $0)]]></finder-query>
    </finder>
    <finder>
     <method-name>findNullAccounts</method-name>
     <method-params>
     </method-params>
     <finder-query><![CDATA[(isNull accountType)]]></finder-query>
    </finder>
   </finder-list>
   <options>
    <use-quoted-names>false</use-quoted-names>
   </options>
  </weblogic-rdbms-bean>

  8.编写ejb部署文件 

  编辑文件weblogic-ejb-jar.xml并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下: 

  <?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>containerManaged</ejb-name>
    <caching-descriptor>
     <max-beans-in-cache>1000</max-beans-in-cache>
    </caching-descriptor>
    <persistence-descriptor>
     <is-modified-method-name>isModified</is-modified-method-name>
     <persistence-type>
      <type-identifier>WebLogic_CMP_RDBMS</type-identifier>
      <type-version>5.1.0</type-version>
      <type-storage>META-INF/weblogic-cmp-rdbms-jar.xml</type-storage>
     </persistence-type>
     <persistence-use>
      <type-identifier>WebLogic_CMP_RDBMS</type-identifier>
      <type-version>5.1.0</type-version>
     </persistence-use>
    </persistence-descriptor>
    <jndi-name>containerManaged.AccountHome</jndi-name>
   </weblogic-enterprise-bean>
  </weblogic-ejb-jar>

5.3.3 编译

  本例中包括服务器端程序和客户端程序,把客户端程序放在一个目录下,这里用C:\bea\wlserver6.0\config\mydomain\clientclasses。如果没有子目录clientclasses,则创建它。
  ·打开命令窗口,进入C:\work\src\examples\ejb\basic\containerManaged目录。
  ·运行设置环境变量命令脚本setEnv.cmd:
   C:\work\src\examples\ejb\basic\containerManaged>c:\work\setEnv
  ·运行编译脚本build.cmd:
   C:\work\src\examples\ejb\basic\containerManaged>build
其中build.cmd代码如下: 


  @REM Copyright (c) 2000 BEA Systems, Inc. All Rights Reserved.
  @REM You must set your environment by running the setExamplesEnv shell script 
  @REM prior to executing this script.

  @REM Create the build directory, and copy the deployment descriptors into it
  mkdir build build\META-INF
  copy *.xml build\META-INF

  @REM Compile EJB classes into the build directory (jar preparation)
  javac -d build Account.java AccountHome.java ProcessingErrorException.java AccountBean.java

  @REM Make a EJB jar file, including XML deployment descriptors
  cd build
  jar cv0f std_ejb_basic_containerManaged.jar META-INF examples
  cd ..

  @REM Run EJBC on jar file
  java -classpath %WL_HOME%/lib/weblogic_sp.jar;%WL_HOME%/lib/weblogic.jar weblogic.ejbc -compiler javac build\std_ejb_basic_containerManaged.jar %WL_HOME%\config\%DOMAIN_NAME%\applications\ejb_basic_containerManaged.jar

  @REM Compile servlets and EJB interfaces into WEB-INF/classes directory of the Examples Web App
  @REM This ensures that the EJB can be accessed by JSPs and servlets of the Examples Web App
  javac -d %EX_WEBAPP_CLASSES% Account.java AccountHome.java ProcessingErrorException.java

  @REM Compile EJB interfaces & client app into the clientclasses directory
  javac -d %CLIENT_CLASSES% Account.java AccountHome.java ProcessingErrorException.java Client.java

5.3.4 定义连接池

  本示例用到连接池demoPool,下面演示如何通过系统管理工具Console为数据库demo定义连接池demoPool。
  (1)启动WebLogic服务器。
  (2)启动系统管理控制台程序console(在浏览器URL中输入http://127:0.0.1:7001/console/,回车)
  (3)点出console控制台左面板的Services/JDBC/Connection Pools,如图5-3所示。
  (4)接下来是一个主要的步骤,点击控制台右面板的“Create a new JDBC ConnectionPool...”,创建新的连接池。进入图5-4的操作界面。定义新的连接池名称Name为demoPool,定义URL为“jdbc:cloudscape:demo”,定义驱动类“Driver ClassName”为“COM.cloudscape.core.JDBCDriver”,义属性Properties为“user=none password=none srver=none”,然后点击“Create”创建。
  (5)预定义连接池的连接数。点击图5-4所示的Connection页,进入图5-5所示的页面,预定义连接“Initial Capacity:”改为:1,“Maximum Capacity:”改为2,“Capacity Increment:”改为1,其余设置不变。点击“Apply”按钮。
  (6)下面就是创建完连接池后,还要把它部署到系统管理的服务器myserve中,点击图5-4的Targets页,在Avaliable栏中选中myserver,点击向右的箭头,点击“Apply”,如图5-6所示。

5.3.5 修改启动脚本

  本示例使用WebLogic Server 6.0 自带的小型关系型数据库cloudscape。因此在WebLogic Server启动的时候,要对启动脚本文件startWebLogic.cmd进行修改。如果还没有修改,则修改如下两个地方:

  1.修改CLASSPATH环境变量

  打开C:\bea\wlserver6.0\config\mydomain目录下的startWebLogic.cmd文件,找到set CLASSPATH=.;.\lib\weblogic_sp.jar;.\lib\weblogic.jar行。把下面的设置加入这行的下一行。设置后,显示如下:
  ...
  set CLASSPATH=.;.\lib\weblogic_sp.jar;.\lib\weblogic.jar
  set CLASSPATH=%CLASSPATH%;.\samples\eval\cloudscape\lib\cloudscape.jar;
  ...

  2.修改启动命令
  找到“%JAVA_HOME%\bin\java”开头的一行,修改这行,增加一个属性项,修改后显示如下:
  "%JAVA_HOME%\bin\java" -hotspot -ms64m -mx64m -classpath %CLASSPATH%
  -Dweblogic.Domain=mydomain -Dweblogic.Name=myserver "-Dbea.home=c:\bea"
  -Dcloudscape.system.home=./samples/eval/cloudscape/data
  "-Djava.security.policy==c:\bea\wlserver6.0/lib/weblogic.policy" 
  -Dweblogic.management.password=%WLS_PW% weblogic.Server
  书写的时候注意文字的有效性。保存startWebLogic.cmd,重新启动WebLogic Server。

5.3.6 运行测试

  首先,启动Weblogic Server 6.0的缺省服务器。
  运行测试程序。继续使用前几个步骤使用的命令窗口,执行:
   C:\work\src\examples\ejb\basic\containerManaged>java
   examples.ejb.basic.containerManaged.Client t3://127.0.0.2:7001/
  观察命令窗口的运行情况,如图5-7所示。
相关新闻
· 5.2 实体对象的生命周期
· 5章 实体EJB (j2ee教程,j2ee电子书
· 4.5 本章小结
· 4.4 有状态会话EJB实例
· 4.3 无状态会话EJB实例
· 4.2 会话EJB编程模型
· 4.1 什么是会话EJB
· 3.5 CORBA协议的标准映射(j2ee教程
· 3.4 会话、实体和消息驱动Bean对象
· 3.3 EJB合约 (j2ee教程)
最近更新
· 如何啃掉司考中的“鸡肋”学科之宪
· 准备司考最有效率的复习方法
· 当今最流行的5种网站推广方法
· 增进PPC广告成效的五个窍门
· 大学生成就业困难户
· 海南旅游职业教育集团成立 培养更多
· 广西地税局多措并举支持职业教育发
· 高职有六特点报考需要三大注意
· 青海2008年成人高校招生细则
· 贵州师范大学2008年成人高考招生简
 
热门院校推荐
· 甘肃金岛汽车职业技术学校
· 哈尔滨唯美设计学校
· 黑龙江新希望职业技能培训学校
· 哈尔滨女王美容美发化妆学校
· 哈尔滨绿豆豆英语学校
· 哈尔滨市劳动和社会保障局技工学校
· 哈尔滨智邦培训
· 新疆机电职业技术学院
· 阿克苏地区技工学校
· 长春新东方一搏职业培训学校
· 甘肃庆阳市华音DJ音乐工作室
· 哈尔滨嘉信会计学校
· 哈尔滨鹰舞舞蹈学校
· 哈尔滨市科海微机外语财会学校
· 哈尔滨创意电脑职业技能培训学校
· 黑龙江李枫美容职业技能培训学校
· 塔城地区中等职业技术学校
· 新疆轻工职业技术学院
· 哈密地区技工学校
· 吉林省黑加伦鬼剪美容美发学校(京华
 
 
 
     
浙江 广东 湖北 黑龙江
安徽 河南 重庆 北京
天津 辽宁 上海 江苏
福建 江西 吉林 河北
湖南 山东 四川 更多>>
赞助广告
最新招生信息
热点新闻
 
高校信息
Zsol.org | 本站承诺 | 战略伙伴•招生分站点 | 友情链接 | 付款方式 | 广告业务 | 联系我们
Copyright © 2005-2008 中国在线招生 | 运营商:杭州骄羽科技有限公司 浙ICP备06036992号
增值电信业务经营许可证:浙B2-20080090