天天看點

精通ejb【五】(轉載)

轉載自:http://www.java-cn.com/technology/technology_detail.jsp?id=785

為Beans增加功能

EJB 上下文:通往容器的門戶

存在如下資訊:

1、關于bean的home對象和EJB對象的資訊

2、bean的目前事務資訊。

3、 對于客戶授權的安全資訊。Bean可以通過查詢環境決定客戶執行操作所需要的安全層次。

4、 bean的環境屬性。

容器将所有這些資訊儲存在一個稱為EJB context object的對象裡。EJB上下文作為容器的實體部分,可以被bean通路。這些通路可以讓bean得到目前的狀态和改變目前的狀态。

上下文可以在bean的生命期中被更改。

EJB1.0 javax.ejb.EJBContext接口:

public interface javax.ejb.EJBContext

{

public javax.ejb.EJBHome getEJBHome();

public java.util.Properties getEnvironment();

public java.security.Identity getCallerIdentity();

public boolean isCallerInRole(java.security.Identity);

public javax.jts.UserTransaction getUserTransaction();

public void setRollbackOnly();

public boolean getRollbackOnly();

}

會話bean的上下文

上下文根據bean的不同分為:會話上下文和實體上下文。它們分别被用于會話bean和實體bean

javax.ejb.EJBContext

public interface javax.ejb.SessionContext

extends javax.ejb.EJBContext

{

public javax.ejb.EJBObject getEJBObject();

}

注意:SessionContext接口繼承了EJBContext接口,在EJBContext中定義的方法提供了對會話bean的存取路徑。

對于會話bean,調用setSessionContext,這個方法在javax.ejb.SessionBean接口中被定義。對于實體bean,調用setEntityContext。

SessionContext.getEJBObject()

在EJB中,beans可以作為其他bean的用戶端。如果一個bean需要調用另外的bean,getEJBObject()方法則是必需的。在java中,對象可以使用this關鍵字儲存自身的參考。在EJB中,bean不能使用this關鍵字給其他bean傳遞對象,這是因為所有的客戶調用bean上的方法都是間接調用bean的EJB對象。Bean可以使用this關鍵字将自己傳給EJB對象。

了解EJB的安全性

首先,用戶端必須是可被鑒别的。

其次,用戶端必須是已經授權的。

第一步:鑒别

不同的EJB容器擁有不同的鑒别用戶端的方法。例如:BEA的WebLogic中,當不同用戶端代碼使用JNDL定位Home對象時,提供不同的使用者名和密碼。

Properties props = System.getProperties();

props.put(Context.SECURITY_PRINCIPAL, "EmployeeA");

props.put(Context.SECURITY_CREDENTIALS, "myPassword1");

Context ctx = new InitialContext(props);

// Use the initial context to lookup home objects...

EJB沒有制定如何鑒别的規範,是以這樣就影響了可移植性。要了解這方面,檢視各類容器的文檔。

當運作這段代碼時,應用伺服器将驗證你的使用者名和密碼,這是應用伺服器規範。許多應用伺服器允許在屬性檔案裡設定使用者名和密碼。這個檔案将在運作時由應用伺服器讀。

進階點的伺服器支援已經存在的驗證系統的整合。例如将使用者名和密碼清單存儲在LDAP伺服器中。

第二步:授權

隻有經過授權的用戶端才可以調用bean中的方法。EJB中有兩種驗證授權的方法:declaratively和programmatically。即:由容器執行所有的授權檢驗、在程式中進行授權檢查。

Declarative授權檢查時,要在配置描述符中聲明bean的授權需要。例如使用BEA的WebLogic伺服器的配置描述符的例子:

(accessControlEntries

submitPurchaseOrder [employees]

approvePurchaseOrder [managers]

DEFAULT [administrators]

); end accessControlEntries

容器将在運作時自動的執行安全檢查。抛會出java.lang.SecurityException異常。

Programmatic授權檢查,必須查詢EJB上下文得到目前用戶端的授權資訊。由兩種方法調用CallerInRole(Identity role)和getCallerIdentity()。

isCallerInRole()

import java.security.Identity;

...

public class MyBean implements SessionBean {

private SessionContext ctx;

...

public void foo() {

Identity id = new MyIdentity("administrators");

if (ctx.isCallerInRole(id)) {

System.out.println("An admin called me");

return;

}

System.out.println("A non-admin called me");

}

}

import java.security.Identity;

public class MyIdentity extends Identity {

public MyIdentity(String id) {

super(id);

}

}

getCallerIdentity()

import java.security.Identity;

...

public class MyBean implements SessionBean {

private SessionContext ctx;

...

public void bar() {

Identity id = ctx.getCallerIdentity();

String name = id.getName();

System.out.println("The caller´s name is " + name);

}

}

了解EJB對象的操作

許多EJB應用程式需要用戶端有與bean斷開的能力,還要有與bean重建連接配接的能力。EJB提供了EJB object handles。EJB對象操作對于EJB對象是一個長生命期的代理。可以用它來重建與EJB對象的連接配接,并保證會話狀态不被丢失。下面是EJB對象操作的代碼

// First, get the EJB object handle from the EJB object.

javax.ejb.Handle myHandle = myEJBObject.getHandle();

// Next, serialize myHandle, and then save it in

// permanent storage.

ObjectOutputStream stream = ...;

stream.writeObject(myHandle);

// time passes...

// When we want to use the EJB object again,

// deserialize the EJB object handle

ObjectInputStream stream = ...;

Handle myHandle = (Handle) stream.readObject();

// Convert the EJB object handle back into an EJB object

MyRemoteInterface myEJBObject =

(MyRemoteInterface) myHandle.getEJBObject();

// Resume calling methods again

myEJBObject.callMethod();

例子:The Puzzle Game “Fazuul”(參考原文)

繼續閱讀