当前位置: 首页 > 图灵资讯 > 技术篇> 编写Enterprise bean的客户端(下)

编写Enterprise bean的客户端(下)

来源:图灵教育
时间:2024-03-03 10:43:58

使用bean的句柄:

  用于引用enterprise的句柄 bean的另一种方法。句柄相当于bean的长指针。您可以从remote接口获得句柄。一旦你有了句柄,你就可以把它写进文件或其他持久的存储器里。以后很容易重新获得句柄,用它重建enterprise bean的引用。

  然而,您只能使用remote接口的句柄来重建bean的引用。您不能使用句柄来创建bean本身。如果在另一个过程中删除bean,或系统崩溃或关闭,并删除bean的例子,当应用程序试图用句柄重建bean的引用时,它将被抛出异常。

  当你不确定bean的例子是否仍然存在时,你可以不使用remote接口的句柄。相反,保存beanhome接口的句柄,然后通过调用create方法或finder方法重新创建bean对象。

  在客户创建bean实例后,可以通过gethandle()获得实例的句柄。一旦有了句柄,就可以把它写进文件里了。以后,客户可以阅读此文件,将读取的对象转换为句柄类型。然后,可以在句柄上调用的geteJBObject方法获得bean的引用。最后,将getejbobject方法返回的值转换为合适的类型。

用句柄引用Bean

Import java.io;

Import javax.ejb.Handle;

……

Cart cart;

……

cart = home.create(cartHolderName,creditcartNumber,expirationDate);

///在cart对象上调用gethander方法获取其句柄。

CartHander=cart.getHandler();

///将hander写入文件。

FileOutputStream f = new FileOutputStream(“carthandle.ser”);

ObjectOutputStream o = new ObjectOutputStream(f);

o.writeObject(myHandle);

o.flush();

o.close();

……

///可以在以后的某个时间从文件中读取handle

FileInputStream fi = new FileInputStream(“carthandle.ser”);

ObjectInputSteam oi = new ObjectInputStream(fi);

///从文件中读取对象,并将其转换为Hander类型。

CartHanle = (Handle)oi.readObject();

Oi.close;

……

///用handle引用bean的实例

try{

Object ref = context.lookup(“cart”);

Cart cart1 = (Cart)javax.rmi.PortableRemoteObject.narrow(ref,Cart.class);

……

}catch(RemoteException e){

……

}

……

  用完会话bean的句柄后,客户将使用javax.ejb.EJBHome.remove(Handle handle)删除句柄的方法。

二、管理事务:

  与其让enterprise,客户程序可以管理自己的事务 bean或容器管理。当客户管理自己的事务时,就像与bean交谈管理自己的事务一样。

  当客户管理自己的事务时,他们需要描述事务的分界线。也就是说,它必须清楚地开始和终止一个事务(提交或回滚)。

  使用javax的客户.transaction.Usertransaction接口管理自己的事务。必须先用JNDI引用Usertransaction接口。一旦有了Usertranscation的上下文,就可以使用Usertransaction.begin()开始一个事务的方法(后来用Usertranscationn.commit()方法提交或Usertransction.rollback()方法回滚此事)。在此期间,客户进行相关查询和更新操作。

  以下代码展示了客户如何管理自己的事务。协议中的客户管理部分通过粗体显示:

客户管理事务:

import javax.naming.initialContext;

import javax.transcation.UserTransaction;

……

public class clientTransaction{

public static void main(String[] argv){

UserTranscation ut=null;

InitialContext initContext = new InitialContext();

……

ut = (UserTransaction)initContext.lookup(“java:comp/UserTranscation”);

//开始事务

ut.begin();

//做事务工作。

……

ut.commit(); //or ut.rollback();

}

}

三、获得enterprise bean信息:

  enterprise bean的信息是指向metadata的引用。客户使用enterprise beanhome接口的getmetadata()方法可以获取bean的metadata信息。

  GetMetaData()开发环境和build工具经常使用该方法,因为它们需要知道enterpriseee bean的相关信息,比如已经安装了哪些链接到一起的bean。脚本客户还需要获取bean的metadata信息。

  一旦客户重新引用home接口。您可以在home接口上调用geteJBMetadata()方法。然后,客户可以通过调用ejbmetadata接口获取以下信息。

  使用EJBMetaDatata.getEJBHome()获取beanEJBHome接口的方法。

  使用EJBMetaDatata.getHomeInterfaecClass()获取home接口类对象的方法。包括其接口、类别、域和方法。

  使用EJBMetaDatata.getRemoteInterfaceClass()获取remote接口类对象的方法。包括所有类信息。

  使用EJBMetaDatata.getPrimaryKeyClass()获取bean主键类对象的方法。

  无论是会话bean还是实体bean。EJBMetadatatatan。.isSession()判断方法。

  使用EJBMetaDatata.isStatelessSession()判断会话bean是否有状态或无状态。

支持JNDI:

  EJB规范定义了定位home接口的API。JNDI是其他服务(CORBA命名服务,LDAP/X.500,flat files,上面实现的目录服务)。下图解释了不同的实现选择。典型的,EJB服务提供商选择特定的JNDI实现。

 

  该技术实现了与客户无关的JNDI底层。客户只需使用JNDIAPI即可。

从EJB到CORBA的映射:

  EJB和CORBA之间有很多联系。有三点很重要:

  EJB容器/服务用ORB实现。

  综合能力将原始系统放入EJB中间层。

  访问EJB的能力来自非java组件的客户。

  目前EJB规范只涉及这三个方面。

  CORBA是一个非常合适和自然的平台,可以实现EJB的下层组织。CORBA提供了所有与CORBA核心规范或CORBA核心服务相关的EJB规范。

持分布式:CORBA核心和CORBA命名服务

支持事务:CORBA对象的服务

支持安全:包括IIOP在内的CORBA安全规范-over-SSL

  此外,CORBA允许非JAVA组件与应用程序的结合。这些组件可以是原始的系统或程序,插入不同的客户。后端系统可以很容易地将OTS与任何可以与IDL映射的程序设计语言结合起来。这要求容器提供OTS和IIOP的APIS。

  EJB规范允许非JAVA客户访问enterprise bean,EJB到CORBA的映射也提供了。EJB/CORBA映射的目的是:

  基于CORBA的EJB服务,支持用任何CORBA支持的程序设计语言编写的客户端和enterprise。 结合bean。

  在相同的事务处理中,客户程序与CORBA对象或enterprisese 结合bean。

  支持在基于CORBA的EJB服务器上运行涉及不同代理提供的多个客户端的分布式事务。

  基于java的映射-to-IDL映射。其规范包括以下几个方面:分布式关系映射、命名约定映射、事务处理映射、安全映射。在下面的部分,我们将解释每一个映射。在OMGObjectt中,由于映射使用了新的IDL特性-by-在Value规范中介绍。与其它语言的结合需要与CORBA2.3ORB规范兼容。

分布式映射:

  enterprise bean有两个可远程访问的接口:remote接口和home接口。在IDL规范中,有这样的JAVA/IDL到这些接口的映射。EJB规范中定义的基类也以同样的方式映射到IDL中。

  比如我们来看看下面的IDL接口,这就是ATM的例子。是enterprise。 会话bean。在accounts之间转账有一种方法。也可以抛出资金不足的异常。通过JAVA/IDL映射其home接口和remote接口。我们得到以下IDL接口:

Module transaction{

Module ejb{

Valuetype InsufficientFundsException: ::java::lang::Exception{};

Exception InsufficientFundsEx{

::transcation::ejb::InsufficientFundsException value;

};

interface Atm: ::javax::ejb::EJBObject{

void transfer(in string arg[], in string arg1, in float arg2)

raise(::transaction::ejb::InsufficientFundsEx);

};

interface AtmHome: ::javax.:ejb::EJBHome{

::transaction::ejb::Atm create{}

raise(::javax::ejb::CreateEx);

};

};

};

命名映射:

  基于CORBA的EJB运行环境,如果所有CORBA客户都能访问enterprise bean,必须使用CORBA命名服务来发布enterprise bean的home接口。可直接使用CORBA命名服务,也可间接使用JNDI及其标准映射到CORBA命名服务。

  用字符串将JNDI命名为以下形式:“directory1/directory2/../directotyN/objectName"。CORBA命名服务将名称定义为一系列名称组件:

Typedef string Istring;

Struct NameComponet{

Istring id;

Istring kind;

};

typedef sequence <NameCompoent> Name;

  每个由“/”分开的JNDI字符串名称都被映射成名称组件。最左边的组件是CORBA命名服务名称的第一个入口。

JNDI字符串的名称与一些命名的上下文有关。我们称之为JNDI根的上下文。JNDI根的上下文相当于CORBA命名服务的初始化。CORBA命名服务的名称与CORBA的初始化有关。

resolv_通过在ORB的虚拟对象上调用initial_reference(“NameService)CORBA应用程序可以获得CORBA最初命名服务的上下文。CORBA命名服务没有规定如何组织命名上下文,因此根上下文的概念不起作用。通过resolve_initial_reference()决定上下文。

例如,C++客户端可以定位我们的ATM会话bean的home接口。这个ATM bean已经用JNDI字符串“transaction/corbaEjb/atm“注册。首先,我们得到上下文的初始命名。

oject_ptr obj = orb->resolve_initial_references(“NameService”);

NameContext initialNameContext = NameingContext.narrow(obj);

if (initialNameingContext == NULL) {

cerr <<”Could not initial naming context” <<endl;

exit(1);

}

然后,我们生成了CORBA命名服务的名称,并根据上述情况初始化。

Name name = new Name(1);

name[0].id=”atm”;

name[0].kind=””;

现在我们解决了初始命名服务的名称问题。假设我们成功地初始化了,我们也有enterprisee bean名字域的上下文。我们将CORBA对象的范围缩小到所需的类型,并确保这种缩小是成功的。

Object_ptr obj=initialNamingContext->resolve(name);

AtmSessionHome_ptr atmSessionHome = AtmSessionHome.narrow(obj);

if (atmSessionHome == NULL){

cerr<<”Could not narrow to ATMSessionHome” <<endl;

exit(1);

}

事务处理映射:

基于CORBA的enterprise 在bean运行过程中,CORBA的客户端需要参与enterprisese 在处理bean的事务时,必须使用CORBA的OTS(Object Transaction Service)控制事务。

enterprise bean配置后,可根据不同的事务服务政策进行安装。该政策在配置描述器中定义。

事务性enterprise bean有以下定义规则:CORBA客户通过IDL接口生成的stub调用enterprise Bean的remote接口和home接口。在事务处理方面,使用CORBA OTS提供的接口。

例如,C++客户可以调用ATM会话bean:

try{

//obtain transaction current

Object_ptr obj = orb->resolve_initial_reference(“Current”);

Current current = Current.narrow(obj);

if(current==NULL){

cerr<<”Could not resolve current ”<<endl;

exit(1);

}

//execute transaction

try{

current->begin();

atmSession->transfer(“checking”,”saving”,100.00);

current->commit(0);

}catch(…){

current->rollback();

}

}catch(…){

……

}

安全映射:

控制enterprise是EJB规范安全的主要考虑因素 bean的访问权限。CORBA规定了一些定义标识符的方法,包括以下几个方面:

Plain IIOP(简单IIOP方法):1998年初,CORBA的主要接口尚未被接受。确定客户标识的主要接口。然而,CORBA安全服务作者实现了不同的方式:GIOP。GIOP规范包括一个称为服务上下文的组件,实际上是一个元素值对的数组。其标识符为CORBAlong型,值为十进制序列。服务上下文的入口可以用来识别调用者。

Secure IIOP(IIOP的可靠方式):CORBA的安全标准为身份定义了一种不透明的数据类型。身份的实际类型取决于所选择的安全机制。例如:GSS Kerberos,SPKM,或者CSI-ECMA。

IIOP over SSL:SSLX(加密套接字协议层).509证明服务器或客户的身份。当服务器需要客户身份验证时,服务器使用该证书作为客户身份验证。