專案建立與服務器配置
- 新建專案: File → New Project,名稱
Trader,格式 XML,EJB 2.0 規範。
- 配置 WebLogic 6.1: Tools → Configure Servers,啟用 WebLogic,設置 Home/JDK/BEA Home 目錄,重啟 JBuilder。
- 專案綁定服務器: Project → Default Project Properties → Server → Single server for all services → WebLogic 6.x+。
EJB 模塊與 Session Bean 創建
- File → New → Enterprise → EJB Module,名稱
Trader,啟動 EJB Designer。
- 右鍵設計面板 → Create EJB → Session Bean:
Bean Name: Trader、Interfaces: Remote、Type: Stateful、Transaction: Container。
字段定義
| 字段名 | 類型 |
_cardHolderName | java.lang.String |
_creditCardNumber | java.lang.String |
_expirationDate | java.util.Date |
_items | java.util.ArrayList |
業務方法
addItem(Item item) — 加入商品
removeItem(Item item) — 移除商品
getContents() : ArrayList — 獲取購物車內容
getTotalPrice() : float — 計算總價
purchase() — 執行購買(檢查卡片有效期)
完整源碼(手動修正後)
TraderBean.java
package trader;
import javax.ejb.*;
import java.util.Date;
import java.util.ArrayList;
public class TraderBean implements SessionBean {
private SessionContext sessionContext;
private String _cardHolderName;
private String _creditCardNumber;
private Date _expirationDate;
private ArrayList _items;
public void ejbCreate(String cardHolderName, String creditCardNumber, Date expirationDate)
throws CreateException {
_items = new ArrayList();
_cardHolderName = cardHolderName;
_creditCardNumber = creditCardNumber;
_expirationDate = expirationDate;
}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext ctx) { this.sessionContext = ctx; }
public void addItem(Item item) {
System.out.println("\taddItem(" + item.getTitle() + "):" + this);
_items.add(item);
}
public void removeItem(Item item) {
System.out.println("\tremoveItem(" + item.getTitle() + "):" + this);
if (!_items.remove(item)) {
throw new EJBException("The item " + item.getTitle() + " is not in your cart.");
}
}
public ArrayList getContents() {
System.out.println("\tgetContents():" + this);
return _items;
}
public float getTotalPrice() {
System.out.println("\tgetTotalPrice():" + this);
float total = 0f;
for (int i = 0, n = _items.size(); i < n; i++) {
Item current = (Item) _items.get(i);
total += current.getPrice();
}
return Math.round(total * 100) / 100f; // 保留兩位小數
}
public void purchase() {
System.out.println("\tpurchase():" + this);
Date today = new Date();
if (_expirationDate.before(today)) {
throw new EJBException("Expiration date: " + _expirationDate);
}
System.out.println("\tPurchasing not implement yet!");
}
}
TraderHome.java
package trader;
import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.Date;
public interface TraderHome extends EJBHome {
Trader create(String cardHolderName, String creditCardNumber, Date expirationDate)
throws CreateException, RemoteException;
}
Trader.java (Remote Interface)
package trader;
import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.ArrayList;
public interface Trader extends EJBObject {
void addItem(Item item) throws RemoteException;
void removeItem(Item item) throws RemoteException;
ArrayList getContents() throws RemoteException;
float getTotalPrice() throws RemoteException;
void purchase() throws RemoteException;
}
Item.java (可序列化值對象)
package trader;
import java.io.Serializable;
public class Item implements Serializable {
private static final long serialVersionUID = -567896319031239L;
private String _title;
private float _price;
private String _type;
public Item(String title, float price, String type) {
_title = title; _price = price; _type = type;
}
public String getTitle() { return _title; }
public float getPrice() { return _price; }
public String getType() { return _type; }
public boolean equals(Object o) {
if (!(o instanceof Item)) return false;
Item i = (Item) o;
return getClass().equals(i.getClass()) &&
(_title == null ? i._title == null : _title.equals(i._title));
}
}
部署與測試
- JBuilder 專案構建:Project → Make/Rebuild Project。
- 部署:在 EJB Module 上右鍵 → Deploy,生成
Trader.jar 至 WebLogic applications 目錄。
- 編寫測試客戶端(Servlet/Standalone)通過 JNDI
ejb/Trader 查找 Home,調用 create() 獲取 Remote,驗證業務流程。
開發提示
- Stateful Bean 需正確實現
ejbActivate/passivate 以支持會話持久化。
- 遠程接口拋出
RemoteException,本地接口則不需(EJB 2.0 新增)。
- 值對象
Item 實現 Serializable 以支持跨 JVM 傳遞。