站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题关于EJB的基本概念和例子2

关于EJB的基本概念和例子2

摘要: 关于EJB的基本概念和例子
Session Bean的構成

一個完整可執行的Session Bean具備:

Bean Class:
包括Session Bean主要的程式碼-程式開發人員所撰寫的Business Logic Method.
Home Interface Class:
內含與Session Bean生命週期相關的Method的介面.
Remote Interface Class:
內含撰寫在Bean Class內Business Logic Method的介面.這是定義client端可以使用的Method
與Property
Deployment descriptor file (.xml):
記錄EJB的各種資訊(class name,JNDI name,交易屬性…等等),供 AP Server將EJB載入時使用.
Container files:
一組由AP Server根據EJB Class所產生的class,AP Server利用這些class建立EJB Container.


除了撰寫Bean Class內的business logic外,尚要實作home和remote兩個介面,不過大部分的開發工具(如JBuilder)都會提供精靈幫助我們產生,所以並不需要自己撰寫。以JBuilder為例,每個EJB要屬於一個EJB Group(這是JBuilder的定義),所以New 一個Empty的EJB Group後,才能再New EJB ,而定義好EJB Bean class的名稱後,便會自動產生Remote Interface/Home Interface,而我們便可以著重在Bean的設計,可以新增Property(有精靈輔助),也可以新增Method(自行在class中加入),最後才在Bean class中選bean的Tab再選Method的Tab,把需要提供給client端使用的Method/Property 選起來,便能自動更新Remote Interface。另外也可以用Wizards Menu/EJB interface 選create interface來自動產生。

EJB存放在EJB Containers內.Client端透過home和remote兩個介面來使用EJB.藉由interface,Client可以知道EJB有哪些功能可以使用,而Container會將EJB與外界隔離,每次EJB被Client呼叫,建立,消滅,都是透過Container來完成這些動作.

Bean Class內包括所有程式開發人員所撰寫的Business Logic Method.特別要注意的是Business Logic
Method必須要宣告為public,並將其放入介面Remote Class中,Client端才能呼叫使用它.
不論Stateful Session Bean或Stateless Session Bean,都是實作(implements)javax.ejb.SessionBean
介面(Interface),所以必須實作javax.ejb.SessionBean定義的ejbCreate,ejbRemove,ejbActivate,
ejbPassivate,setSessionContext等五個call back method,這些method與Session Bean的生命週期相關,
當Session Bean被建立,移除,鈍化,活化時,EJB Container會呼叫對應的method,並執行其中的程式碼.在撰
寫Session Bean時一定要宣告這些method,即使沒有程式碼也沒關係(無程式碼只是當EJB Container呼叫該mehtod時,不會做任何事).

ejbCreate:
在Session Bean Instance的生命週期中,ejbCreate()會在最初Instance建立後被EJB Container
呼叫一次,我們可以將初始化的程式碼(如設定變數值)寫在這裡.
ejbRemove:
EJB Container移除Session Bean Instance之前會先呼叫此method.我們可以將一些善後的程式碼
(如關閉Connection,釋放Object)寫在這裡.
ejbActivate:
only for Stateful Session Bean(註一) & Entity Bean。當Client端再次呼叫先前用過的
Stateful Session Bean時,AP Server會建立一個新的Stateful Session Bean,並放入原先儲存在硬碟
中的state,然後呼叫ejbActivate( )
ejbPassivate:
only for Stateful Session Bean(註一) & Entity Bean):Stateful Session Bean Instance
閒置超過設定之最大容忍時間後,為節省系統資源,AP Server會將State寫入硬碟,然後消滅該Instance.
在AP Server開始執行這個過程之前,會先呼叫ejbPassivate( )
setSessionContext:
提供一個與EJB Container聯繫的Interface:SessionContext;我們可以透過
SessionContext取得與Session Bean Instance相關的訊息,如呼叫者的身份,交易狀態等等.

註一:因為Stateful Session Bean與Stateless Session Bean都同樣實作javax.ejb.SessionBean這個
Interface,所以在撰寫時都必須宣告ejbActivate與ejbPassivate.但這兩個method只會在Stateful
Session Bean內發生作用,所以若是撰寫Stateless Session Bean,對於ejbActivate與ejbPassivate
可置之不理.

Session Bean的標準的範例:
package com.syscom;
import java.rmi.*;
import javax.ejb.*;
public class statefulBean implements SessionBean {
private SessionContext sessionContext;
public void ejbCreate() {
}

public void ejbRemove() {
}

public void ejbActivate() {
}

public void ejbPassivate() {
}

public void setSessionContext(SessionContext context) {
sessionContext = context;
}

}

每個Session Bean都有一個Remote Interface,內含其Bean Class的Business Logic Method的介面.
Client端呼叫Session Bean時,必須透過其Remote Interface Object(也就是EJB Object)幫它呼叫在
Bean Class內相對應的Business Logic Method,Client端無法與Session Bean Instance接觸,而Client
所能呼叫的method,僅限於Remote Interface中有宣告的method.


以下是一個Session Bean的Bean Class與Remote Interface Class範例:
package com.syscom.cghdemo.sejb.scrutinize;
import java.rmi.*;
import javax.ejb.*;
import java.util.*;
omport java.io.*;
import javax.naming.*;
import syscom.cghdemo.eejb.regvhist.*;

public class MyTestBean implements SessionBean {

private SessionContext sessionContext;
public String[] SerachPatient(String idno) throws RemoteException{
try{
System.out.println("\nBeginning SerachPatient ...\n");
String[] PatientData = new String[4];
javax.naming.Context ctx1 = getInitialContext();

regvhistHome home1 = (regvhistHome)javax.rmi.PortableRemoteObject.narrow(ctx1.lookup("regvhist"),regvhistHome.class);
regvhist loaddata1 = home1.findByIdCode(idno);
PatientData[0] = loaddata1.getChineseName();
PatientData[1] = loaddata1.getChartNo();
PatientData[2] = loaddata1.getSex();
PatientData[3] = loaddata1.getEnglishName();
return PatientData;
} catch (Exception ex) {
String[] PatientData = new String[1];
PatientData[0] = "Error";
System.out.println("Error:"+ex);
return PatientData;
}

}
public String Inserttristria(String[] PD) throws IOException {
System.out.println("\nBeginning Inserttristria ...\n");
}
public int GetMyID() {
return 1;
}
public void ejbCreate() throws CreateException {
//未實作
}
public void ejbRemove() throws RemoteException {
//未實作
}
public void ejbActivate() throws RemoteException {
//未實作
}
public void ejbPassivate() throws RemoteException {
//未實作
}
public void setSessionContext(SessionContext context) throws RemoteException {
sessionContext = context;
}
private static Context getInitialContext() throws NamingException {
try {
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, "t3://localhost:7001");
return new InitialContext(h);
} catch (NamingException ne) {
System.out.println("unable to get a connection to the WebLogic server");
throw ne;
}
}
}


/**
*Remote Interface Class
*/

package com.syscom.cghdemo.sejb.scrutinize;
import java.rmi.*;
import javax.ejb.*;

public interface scrutinize extends EJBObject {
public String[] SerachPatient(String idno) throws RemoteException, RemoteException;
public String Inserttristria(String[] PD) throws IOException, RemoteException;
public int GetMyID() throws RemoteException;
}


觀察以上的範例,可以發現

1.Remote Interface Class內所宣告的method介面,必須是Bean Class內有的method
2.Bean Class內的call back method,如ejbCreate,ejbRemove,ejbActivate,ejbPassivate,
setSessionContext,都不可以放到Remote Interface Class內,因為這些call back method是專屬於EJB
Container,當Session Bean到達其生命週期都每個階段,EJB Container就會自動觸發相關的call back
method.
3.Bean Class內的method不一定要全部放到Remote Interface Class內,例如像範例中的getInitialContext
,是Bean Class內其他method所要使用的與Client端無關,所以我們就不需要將其介面放入Remote Interface Class.換句話說,我們只需要將要給Client端使用的method放入Remote Interface Class.

4.Bean與Remote Interface對Method的定義有些不同,Remote Interface多了Throws RemoteException


Home Interface定義Session Bean生命週期的method(如create, remove..等等).client可以呼叫home
interface所定義的method去建立,消滅,Session Bean的instance.

我們延續上面範例,以下是它的Home Interface Class:

package com.syscom.cghdemo.sejb.scrutinize;
import java.rmi.*;
import javax.ejb.*;
public interface scrutinizeHome extends EJBHome {
public scrutinize create( ) throws CreateException, RemoteException;
}


一般來說,Session Bean的Home Interface Class內只存在create的method,而在Stateless Session Bean
的Home Interface Class中,只能擁有一個沒有參數傳入的create( ) method(因為就算它有需傳入參數的
create(),它也沒辦法幫你保留client傳過來的資料,因為它是stateless)

先前中提到Remote Interface宣告的method,必須是Bean Class內已經有撰寫的method.當Client端透過
Remote Interface呼叫某些method時,實際上會呼叫到Bean Class內相對應的Business Logic Method.
問題來了,在Home Interface內宣告的create method,但它與Remote Interface一樣,也只是一個介面,我們
要所執行相對應的程式碼在哪裡呢? create與remove處理的情形不大相同,讓我們分開來看.

1.create
每個EJB的Home Interface一定都會宣告create method,以供Client端呼叫建立EJB的instance.而當
Client端呼叫create method後,EJB container會建立該EJB的Instance並自動呼叫其ejbCreate(),但
ejbCreate並不是真正create method相對應所要執行的程式碼,它只是當Instance被建立起來時,EJB
container所自動呼叫的call back method,裡頭大部分都是一些初始化的程式碼.實際上,當Home Interface
Class在部署至AP Server時,WLSBuilder會根據EJB的設定與Home Interface Class的內容自動產生create
method相對應的程式碼,EJB Container便是利用這一些程式碼建立Instance。實際上若是stateless Session Bean,client端Create時並不一定會呼叫ejbCreate(),因為stateless Session Bean會在Pool之中,
當它放入Pool中時,其實早就執行過ejbCreate(),而Client端的create動作其實只是到Pool中找一
Bean Instance 與EJB Object結合


2.remove
remove與create的運作方式很像,都是由AP Server的WLSBuilder產生真正執行的程式碼.但奇怪的是,為什麼我們不用在Home Interface內宣告remove method呢?可以確定的是,remove method是存在的,在Bean
Class內的ejbRemove是它執行前EJB Container所會自動執行的method,而WLSBuilder後會幫它產生相對應的程式碼,唯一找不到的就是可以讓Client端看到,供Client呼叫的method介面(因為Remove是系統控制的).到底remove()的介面在哪裡?答案:remove method的介面在EJBHome裡.Home Interface是繼承自
javax.ejb.EJBHome這個Interface.底下是javax.ejb.EJBHome的原始碼:
package javax.ejb;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface EJBHome extends Remote {
public abstract EJBMetaData getEJBMetaData()
throws RemoteException;
public abstract HomeHandle getHomeHandle()
throws RemoteException;
public abstract void remove(Object obj)
throws RemoteException, RemoveException;
public abstract void remove(Handle handle)
throws RemoteException, RemoveException;
}


由上面的javax.ejb.EJBHome原始碼中可以發現,其實remove method已經在這裡宣告了,因為Home Interface是繼承自javax.ejb.EJBHome,所以它也具有remove method的宣告,因此我們就不用再次宣告了.
stateless的Session Bean也不會在Client下Remove時去執行ejbRemove(),因為此時只是Release EJB Object,並把Session Bean還到Pool之中。


EJB Home Object
當Client端透過JNDI Name[註一]呼叫位於AP Server上的EJB時,EJB Container會使用Home Interface Class建立EJB Home Object,並將reference傳給Client端.Client端呼叫EJB Home Object內的create method,EJB Home Object會使用Remote Interface Class建立EJB Object並傳回EJB Object的reference。Client取得reference即可呼叫EJB Object內的Business Logic Method.
註一:EJB部署至AP Server時,在WLSBuilder必須設定其JNDI Name(不可以重複).Client(或者是其他的EJB)透過此JNDI Name即可以找到該EJB,並使用它.

EJB Object
EJB Container使用Remote Interface Class建立EJB Object。EJB Object,扮演Proxy角色,Client端透過它
來使用Instance內有release出來[註一]的Business Logic Method。Client端程式必須透過EJB Object,
不能直接呼叫EJB Instance.
註一:所謂“有release出來”是指Bean Class內的Business Logic Method,有將介面放置到Remote
Interface內供Client端呼叫者.

Client端呼叫EJB的流程:

1.client產生home stub
2.透過RMI or CORBA 呼叫遠端的EJB Server
3.EJB Container建立EJB home object(implement from home interface)
4.EJB home object將其reference pass給EJB object
5.建立EJB object(implement from remote interface)
6.Client端的home stub object取得server上EJB object的reference
7.Home stub將EJB object的reference pass給remote stub
8.client產生remote stub
9.client由remote stub,使用EJB object上有定義的method
10.EJB object將client的要求pass給enterprise bean
11.enterprise bean將運算好的結果pass給EJB object
12.EJB object將結果傳回client

EJB的Deploy
JAR是一種標準的ZIP檔案格式.在EJB中使用JAR的目的,是將相關的class,interface,xml descriptor,都封
裝在一個檔案中,以方便管理,部署.
當我們做好了Bean Class,Remote Interface Class,Home Interface Class,Deployment descriptor file,
與Container files後我們就可以將它們包裝成一個Jar.一個Jar可以容納一個以上的EJB,在,Deployment
descriptor files內會詳細紀錄Jar內存放的Class的相關資料,與相對存放位置.
在Jar內需要有一個名為META-INF的目錄,ejb-jar.xml與weblogic-ejb-jar.xml都必須放在這邊.另外要注
意的是,Jar內的目錄結構需要與EJB的package結構相對應.(這些動作可在jBuilder中輕易完成)
當Jar製作完成之後,我們就可以將它部署到AP Server上了。在WebLogic6.1中可使用console程式來部署。

Stateless EBJ的範例
本範例是一個身分證檢查程式.以下將會介紹Bean Class,Home Interface Class,Remote Interface Class
以及Test Client的寫法.至於如何產生Deployment descriptor file與Container files則會在實例操作中
為大家說明.

package sample.ejb.session.stateless;
import java.rmi.*;
import javax.ejb.*;

//在撰寫EJB時,通成為了方便,我們至少都會import java.rmi.*與javax.ejb.*兩組class
public class CheckBean implements SessionBean
{
private SessionContext sessionContext;
public void ejbCreate()
{
//callback method
}
public void ejbRemove()
{
//callback method
}
public void ejbActivate()
{
//callback method
}
public void ejbPassivate()
{
//callback method
}
public void setSessionContext(SessionContext context)
{
//callback method
sessionContext = context;
//EJB Container呼叫setSessionContext時會將Bean Instance的SessionContext傳入
//我們將其reference複製到context變數中,之後便可利用context變數取得Instance的
//相關資訊,
}
/**
* 檢查身份證號是否正確的method
* @param ID 身份證號
* @return 正確嗎(true or false)?
*/
public boolean isIDCorrect(String ID){
boolean isCorrect = true;
String MapTable = new String("ABCDEFGHJKLMNPQRSTUVXY");
String C = new String("1987654321");
String PID = ID.toUpperCase();
StringBuffer str = new StringBuffer("");

int i=0,n=0;

if (PID.length()!=10)
return(false);
if (('A'>PID.charAt(0)) || (PID.charAt(0)>'Z')){
isCorrect = false;
}
else if (PID.length() != 10){
isCorrect = false;
}
for (i=1;i<=9;i++){
if (('0'>PID.charAt(i)) || (PID.charAt(i)>'9'))
isCorrect = false;
}
str.append(String.valueOf(10 + MapTable.indexOf(PID.charAt(0),0)));
str.append(PID.substring(1));
for (i=0,n=0;i<10;i++){
n += Integer.valueOf(String.valueOf(str.charAt(i))).intValue() *
Integer.valueOf(String.valueOf(C.charAt(i))).intValue();
}

n = 10 - n % 10;

if (n != Integer.valueOf(String.valueOf(PID.charAt(9))).intValue()){
isCorrect = false;
}

return(isCorrect);
}
}


-----------------------------------------------------------------------------------------------------------------
package sample.ejb.session.stateless;
import java.rmi.*;
import javax.ejb.*;
public interface CheckHome extends EJBHome
{
public Check create() throws RemoteException, CreateException; //一定要有這兩個Exception
}

-----------------------------------------------------------------------------------------------------------------
package sample.ejb.session.stateless;
import java.rmi.*;
import javax.ejb.*;
public interface Check extends EJBObject
{
public boolean isIDCorrect(java.lang.String ID) throws RemoteException; //一定要有這Exception
}

------------------------------------------------------------------------------------------------------------------
//這是Testing該EJB的client程式
package sample.ejb.session.stateless;
import javax.naming.*;
import java.util.*;
public class CheckBeanTestClient
{
public static void main(String[] args)
{
Context ctx = null;
CheckHome checkHome = null;
Check check = null;
try {
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,"t3://localhost:7001");
ctx = new InitialContext(ht);
//以上四行程式用來取得與WLS的聯繫,其中localhost要改成WLS所在電腦的IP
checkHome = (CheckHome)ctx.lookup("sample.ejb.session.stateless.CheckBean");
//EJB部署到WLS需設定其JNDI name.當Client端要呼叫EJB時,便使用Context.lookup(),
//傳入JNDI name,即可找到該EJB的Home Interface.WLS會使用Home Interface建立
//EJB Home,並將其reference傳給Client端.

check = checkHome.create();
//使用Home Interface內的create()建立Remote Interface.

System.out.println("身份證號 : A200000003 " + (check.isIDCorrect("A200000003")?"正確":"錯誤"));

//利用Remote Interface呼叫EJB內的Business Logic Method
System.out.println("身份證號 : A200000001 " + (check.isIDCorrect("A200000001")?"正確":"錯誤"));

}catch (Exception ex) {
System.err.println(ex.getMessage());
//顯示錯誤訊息
}
finally{
try {
ctx.close();
//將ctx消滅
} catch (Exception ex) {}
}
}
}


----------------------------------------------------------------------------------------------------------------------
Stateful Section Bean範例

package sample.ejb.session.stateful;
import java.rmi.*;
import javax.ejb.*;
import java.util.*;

public class CartBean implements SessionBean // 若需有transaction event,則implements後需再加 SessionSynchronization
{
private SessionContext sessionContext;
private Vector Items = new Vector();
private String CardHolderName;
private String CreditCardNumber;
private Date ExpirationDate;

public void ejbCreate(String cardHolderName, String creditCardNumber, Date expirationDate)
{
this.CardHolderName = cardHolderName;
this.CreditCardNumber = creditCardNumber;
this.ExpirationDate = expirationDate;
} //此時的ejbCreate便可以有參數的傳入了,這和Home的Create()參數有一致

public void ejbRemove(){}
public void ejbActivate(){}
public void ejbPassivate() {}
public void setSessionContext(SessionContext context) {
sessionContext = context;
}
/**
* 需有transaction event時,請實作下列3個method
* public void afterBegin(){}
* public void beforeCompletion(){}
* public void afterCompletion(boolean committed){}
*/
public void addItem(Item item) {
System.out.println("\t增加品名(" + item.getTitle() + "): " + this);
this.Items.addElement(item);
}
public void removeItem(Item item) throws ItemNotFoundException {
System.out.println("\t移除品名(" + item.getTitle() + "): " + this);
Enumeration elements = this.Items.elements();
while(elements.hasMoreElements()) {
Item current = (Item) elements.nextElement();
// items are equal if they have the same class and title
if(item.getClass().equals(current.getClass()) &&
item.getTitle().equals(current.getTitle())) {
this.Items.removeElement(current);
return;
}
}
throw new ItemNotFoundException("項目 " + item.getTitle() + " 不在購物車中!!");
}
public float getTotalPrice() {
System.out.println("\t總價(): " + this);
float totalPrice = 0f;
Enumeration elements = this.Items.elements();
while(elements.hasMoreElements()) {
Item current = (Item) elements.nextElement();
totalPrice += current.getPrice();
}
// round to the nearest lower penny...
return (long) (totalPrice * 100) / 100f;
}

public java.util.Enumeration getContents() {
System.out.println("\t列出購物車內品名(): " + this);
return new VectorEnumeration(this.Items);
}
public void purchase() throws PurchaseProblemException {
System.out.println("\t交易(): " + this);
// 確定信用卡尚未過期
Date today = Calendar.getInstance().getTime();
if(this.ExpirationDate.before(today)) {
throw new CardExpiredException("信用卡有效期限 : " + this.ExpirationDate);
}
// 將資料 update 進資料庫
System.out.println("==========================================");
}
public String toString() {
return "CartBean[姓名:" + this.CardHolderName + "]";
}
}

----------------------------------------------------------------------------------------------------
package sample.ejb.session.stateful;
import java.rmi.*;
import javax.ejb.*;
import java.util.Date;
public interface CartHome extends EJBHome {
public Cart create(String cardHolderName, String creditCardNumber, Date expirationDate)
throws RemoteException, CreateException;
}

-----------------------------------------------------------------------------------------------------
package sample.ejb.session.stateful;
import java.rmi.*;
import javax.ejb.*;
import java.util.Enumeration;

public interface Cart extends EJBObject {
public void addItem(Item item) throws RemoteException;
public void removeItem(Item item) throws ItemNotFoundException, RemoteException;
public float getTotalPrice() throws RemoteException;
public Enumeration getContents() throws RemoteException;
public void purchase() throws PurchaseProblemException, RemoteException;
}

------------------------------------------------------------------------------------------------------
package sample.ejb.session.stateful;
import java.util.*;
import javax.naming.*;
class Book extends Item {
Book(String title, float price) {
super(title, price);
}
}

class CompactDisc extends Item {
CompactDisc(String title, float price) {
super(title, price);
}
}

public class CartBeanTestClient {
static void summarize(Cart cart) throws Exception {
System.out.println("======= 購物車內所含品名 ========");
Enumeration elements = cart.getContents();
while(elements.hasMoreElements()) {
Item current = (Item) elements.nextElement();
System.out.println("單價 : $" + current.getPrice() + "\t" +
current.getClass().getName() + " title: " + current.getTitle());
}
System.out.println("總價 : $" + cart.getTotalPrice());
System.out.println("=================================");
}
public static void main(String[] args) throws Exception {
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,"t3://localhost:7001");
Context ctx = new InitialContext(ht);
CartHome home = (CartHome)ctx.lookup("sample.ejb.session.stateful.CartBean");
Cart cart;
{
String cardHolderName = "Rex Cheng";
String creditCardNumber = "1234-5678-9012-3456";
Date expirationDate = new GregorianCalendar(2002, Calendar.JULY, 1).getTime();
cart = home.create(cardHolderName, creditCardNumber, expirationDate);
}
Book knuthBook = new Book("JAVA Servlet 設計", 760f);
cart.addItem(knuthBook);
CompactDisc milesAlbum = new CompactDisc("張惠妹", 340f);
cart.addItem(milesAlbum);
summarize(cart);
cart.removeItem(knuthBook);
Book weedonBook = new Book("Java 入門", 560f);
cart.addItem(weedonBook);
summarize(cart);
try {
cart.purchase();
System.out.println("交易成功");
}
catch(PurchaseProblemException e) {
System.out.println("交易失敗:\n\t" + e);
}
cart.remove();
}
}

-------------------------------------------------------------------------------------------------
Item.java
package sample.ejb.session.stateful;
import java.io.Serializable;
public class Item implements Serializable
{
private String Title;
private float Price;
public Item(String title, float price) {
this.Title = title;
this.Price = price;
}
public String getTitle() {
return this.Title;
}
public float getPrice() {
return this.Price;
}
}


VectorEnumeration.java
package sample.ejb.session.stateful;
import java.util.*;
/**
* 因 JDK 標準的 Enumeration 沒有實作 java.io.Serializable,
* 所以沒有辦法透過 RMI (或 RMI-over-IIOP) 的機制傳送。
* 所以我們自行實作一個簡單的 VectorEnumeration,實作 Enumeration及java.io.Serializable
*/

class VectorEnumeration implements Enumeration, java.io.Serializable {
private Vector vector;
private transient Enumeration enumeration;
public VectorEnumeration(Vector vector) {
this.vector = vector;
}
private synchronized Enumeration getEnumeration() {
if(this.enumeration == null) {
this.enumeration = this.vector.elements();
}
return this.enumeration;
}
public boolean hasMoreElements() {
return getEnumeration().hasMoreElements();
}
public Object nextElement() {
return getEnumeration().nextElement();
}
}


---------------------------------------------------------------------------------------------------------
CardExpiredException.java:
package sample.ejb.session.stateful;
public class CardExpiredException extends PurchaseProblemException {
public CardExpiredException(String message) {
super(message);
}
}

ItemNotFoundException.java:
package sample.ejb.session.stateful;
public class ItemNotFoundException extends Exception {
public ItemNotFoundException(String message) {
super(message);
}
}


PurchaseProblemException.java:
package sample.ejb.session.stateful;
public class PurchaseProblemException extends Exception {
public PurchaseProblemException(String message) {
super(message);
}
}

-------------------------------------------------------------------------------------------------------------
↑返回目录
前一篇: jboss下ejb简介
后一篇: 关于EJB的基本概念和例子