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;
}
}
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;
}
package com.syscom.cghdemo.sejb.scrutinize;
import java.rmi.*;
import javax.ejb.*;
public interface scrutinizehome extends ejbhome {
public scrutinize create( ) throws createexception, remoteexception;
}
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;
}
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
}
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) {}
}
}
}
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();
}
}
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;
}
}
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();
}
}
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);
}
}
package sample.ejb.session.stateful;
public class purchaseproblemexception extends exception {
public purchaseproblemexception(string message) {
super(message);
}
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器