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_PRINC 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對象是一個長生命期的代理??梢杂盟鼇碇亟ㄅcEJB對象的連接,并保證會話狀態不被丟失。下面是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”