📄 master-ejb-5.htm
字号:
<html><!-- #BeginTemplate "/Templates/more.dwt" -->
<head>
<!-- #BeginEditable "doctitle" -->
<title>csdn_精通ejb【五】</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<STYLE type=text/css>
A:link {
COLOR: #000000; FONT-FAMILY:verdana,宋体,新宋体; TEXT-DECORATION: none
}
A:visited {
COLOR: #333399; FONT-FAMILY:verdana,宋体,新宋体; TEXT-DECORATION: none
}
A:active {
COLOR: #ff0000; FONT-FAMILY:verdana,宋体,新宋体; TEXT-DECORATION: none
}
A:hover {
COLOR: black; TEXT-DECORATION: underline
}
BODY {
COLOR: #000000; FONT-SIZE:9pt; LETTER-SPACING: normal; LINE-HEIGHT: 150%; WORD-SPACING: 2em
}
TH {
FONT-SIZE: 9pt
}
TD {
FONT-SIZE: 9pt
}
TD.page {
COLOR: #000000; FONT-SIZE:9pt; LETTER-SPACING: normal; LINE-HEIGHT: 150%; WORD-SPACING: 2em
}
TD.title {
COLOR: #000000; FONT-FAMILY:verdana,宋体,新宋体
}
TD.detail {
COLOR: #9966ff; FONT-FAMILY:verdana,宋体,新宋体
}
</STYLE>
</head>
<body bgcolor="#FFFFFF" text="#000000" >
<div align="center"></div>
<table width="700" border="0" align="center">
<tr>
<table width="700" border="1" cellpadding="1" cellspacing="0" bordercolorlight="#9898ba" bordercolordark="#000000">
</table>
<table width="700" cellspacing="0" cellpadding="0" bgcolor="9898ba" border="0">
<tr valign="middle"></tr>
</table>
<div align="center"><b></div>
<br>
<table width="700" border="0">
<tr>
<td width="20"> </td>
<td colspan="2">
<div align="center">
<h3><b><!-- #BeginEditable "5" -->
<h3><font face="Verdana, Arial, Helvetica, sans-serif" ><b>精通ejb【五】</b></font></h3>
<!-- #EndEditable --></b></h3>
</div>
</td>
<td width="20"> </td>
</tr>
<tr>
<td width="20"> </td>
<td colspan="2"><!-- #BeginEditable "6" -->
<p>为Beans增加功能 </p>
<p>EJB 上下文:通往容器的门户 <br>
存在如下信息: <br>
1、关于bean的home对象和EJB对象的信息 <br>
2、bean的当前事务信息。 <br>
3、 对于客户授权的安全信息。Bean可以通过查询环境决定客户执行操作所需要的安全层次。 <br>
4、 bean的环境属性。 <br>
容器将所有这些信息保存在一个称为EJB context object的对象里。EJB上下文作为容器的物理部分,可以被bean访问。这些访问可以让bean得到当前的状态和改变当前的状态。
<br>
上下文可以在bean的生命期中被更改。 <br>
EJB1.0 javax.ejb.EJBContext接口: <br>
public interface javax.ejb.EJBContext <br>
{ <br>
public javax.ejb.EJBHome getEJBHome(); <br>
public java.util.Properties getEnvironment(); <br>
public java.security.Identity getCallerIdentity(); <br>
public boolean isCallerInRole(java.security.Identity); <br>
public javax.jts.UserTransaction getUserTransaction(); <br>
public void setRollbackOnly(); <br>
public boolean getRollbackOnly(); <br>
} <br>
会话bean的上下文 <br>
上下文根据bean的不同分为:会话上下文和实体上下文。它们分别被用于会话bean和实体bean </p>
<p>javax.ejb.EJBContext <br>
public interface javax.ejb.SessionContext <br>
extends javax.ejb.EJBContext <br>
{ <br>
public javax.ejb.EJBObject getEJBObject(); <br>
} <br>
注意:SessionContext接口继承了EJBContext接口,在EJBContext中定义的方法提供了对会话bean的存取路径。
<br>
对于会话bean,调用setSessionContext,这个方法在javax.ejb.SessionBean接口中被定义。对于实体bean,调用setEntityContext。
<br>
SessionContext.getEJBObject() <br>
在EJB中,beans可以作为其他bean的客户端。如果一个bean需要调用另外的bean,getEJBObject()方法则是必需的。在java中,对象可以使用this关键字保存自身的参考。在EJB中,bean不能使用this关键字给其他bean传递对象,这是因为所有的客户调用bean上的方法都是间接调用bean的EJB对象。Bean可以使用this关键字将自己传给EJB对象。
<br>
了解EJB的安全性 <br>
首先,客户端必须是可被鉴别的。 <br>
其次,客户端必须是已经授权的。 <br>
第一步:鉴别 <br>
不同的EJB容器拥有不同的鉴别客户端的方法。例如:BEA的WebLogic中,当不同客户端代码使用JNDL定位Home对象时,提供不同的用户名和密码。
<br>
Properties props = System.getProperties(); <br>
props.put(Context.SECURITY_PRINCIPAL, "EmployeeA"); <br>
props.put(Context.SECURITY_CREDENTIALS, "myPassword1");
<br>
Context ctx = new InitialContext(props); <br>
// Use the initial context to lookup home objects... <br>
EJB没有制定如何鉴别的规范,因此这样就影响了可移植性。要了解这方面,查看各类容器的文档。 <br>
当运行这段代码时,应用服务器将验证你的用户名和密码,这是应用服务器规范。许多应用服务器允许在属性文件里设置用户名和密码。这个文件将在运行时由应用服务器读。
<br>
高级点的服务器支持已经存在的验证系统的整合。例如将用户名和密码列表存储在LDAP服务器中。 <br>
第二步:授权 <br>
只有经过授权的客户端才可以调用bean中的方法。EJB中有两种验证授权的方法:declaratively和programmatically。即:由容器执行所有的授权检验、在程序中进行授权检查。
<br>
Declarative授权检查时,要在配置描述符中声明bean的授权需要。例如使用BEA的WebLogic服务器的配置描述符的例子:
<br>
(accessControlEntries <br>
submitPurchaseOrder [employees] <br>
approvePurchaseOrder [managers] <br>
DEFAULT [administrators] <br>
); end accessControlEntries <br>
容器将在运行时自动的执行安全检查。抛会出java.lang.SecurityException异常。 <br>
Programmatic授权检查,必须查询EJB上下文得到当前客户端的授权信息。由两种方法调用CallerInRole(Identity
role)和getCallerIdentity()。 <br>
isCallerInRole() <br>
import java.security.Identity; <br>
... <br>
public class MyBean implements SessionBean { <br>
private SessionContext ctx; <br>
... <br>
public void foo() { <br>
Identity id = new MyIdentity("administrators"); <br>
if (ctx.isCallerInRole(id)) { <br>
System.out.println("An admin called me"); <br>
return; <br>
} <br>
System.out.println("A non-admin called me"); <br>
} <br>
} </p>
<p>import java.security.Identity; <br>
public class MyIdentity extends Identity { <br>
public MyIdentity(String id) { <br>
super(id); <br>
} <br>
} <br>
getCallerIdentity() <br>
import java.security.Identity; <br>
... <br>
public class MyBean implements SessionBean { <br>
private SessionContext ctx; <br>
... <br>
public void bar() { <br>
Identity id = ctx.getCallerIdentity(); <br>
String name = id.getName(); <br>
System.out.println("The caller's name is " + name); <br>
} <br>
} <br>
了解EJB对象的操作 <br>
许多EJB应用程序需要客户端有与bean断开的能力,还要有与bean重建连接的能力。EJB提供了EJB object handles。EJB对象操作对于EJB对象是一个长生命期的代理。可以用它来重建与EJB对象的连接,并保证会话状态不被丢失。下面是EJB对象操作的代码
<br>
// First, get the EJB object handle from the EJB object. <br>
javax.ejb.Handle myHandle = myEJBObject.getHandle(); <br>
// Next, serialize myHandle, and then save it in <br>
// permanent storage. <br>
ObjectOutputStream stream = ...; <br>
stream.writeObject(myHandle); <br>
// time passes... <br>
// When we want to use the EJB object again, <br>
// deserialize the EJB object handle <br>
ObjectInputStream stream = ...; <br>
Handle myHandle = (Handle) stream.readObject(); <br>
// Convert the EJB object handle back into an EJB object <br>
MyRemoteInterface myEJBObject = <br>
(MyRemoteInterface) myHandle.getEJBObject(); <br>
// Resume calling methods again <br>
myEJBObject.callMethod(); <br>
例子:The Puzzle Game “Fazuul”(参考原文) <br>
</p>
<!-- #EndEditable --></td>
</tr>
</table>
<div align="center">
<br>
</div>
</body>
<!-- #EndTemplate --></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -