为beanss增加功能 1、关于beans的home对象和EJB对象的信息
2、beans的当前事务信息
3、对于客户授权的安全信息。beans可以通过查询环境决定客户执行操作所需要的安全层次
4、beans的环境属性
容器将所有这些信息保存在一个称为EJB context object的对象里。EJB上下文作为容器的物理部分,可以被beans访问。这些访问可以让beans得到当前的状态和改变当前的状态。上下文可以在beans的生命期中被更改。
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();
}
会话beans的上下文,上下文根据beans的不同分为:会话上下文和实体上下文。它们分别被用于会话beans和实体beans。
Javax.ejb.EJBContext
public interface Javax.ejb.SessionContext
extends Javax.ejb.EJBContext
{
public Javax.ejb.EJBObject getEJBObject();
}
注意:
SessionContext接口继承了EJBContext接口,在EJBContext中定义的方法提供了对会话beans的存取路径。对于会话beans,调用setSessionContext,这个方法在Javax.ejb.Sessionbeans接口中被定义。对于实体beans,调用setEntityContext。
SessionContext.getEJBObject()
在EJB中,beanss可以作为其他beans的客户端。如果一个beans需要调用另外的beans,getEJBObject()方法则是必需的。在Java中,对象可以使用this关键字保存自身的参考。在EJB中,beans不能使用this关键字给其他beans传递对象,这是因为所有的客户调用beans上的方法都是间接调用beans的EJB对象。beans可以使用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服务器中。
第二步:授权 只有经过授权的客户端才可以调用beans中的方法。EJB中有两种验证授权的方法:declaratively和programmatically。即:由容器执行所有的授权检验、在程序中进行授权检查。
Declarative授权检查时,要在配置描述符中声明beans的授权需要。例如使用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 Mybeans implements Sessionbeans {
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 Mybeans implements Sessionbeans {
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应用程序需要客户端有与beans断开的能力,还要有与beans重建连接的能力。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();