这一节介绍如何使用RMI/IIOP协议访问应用服务器,和如何使用应用客户端容器开发和打包应用客户端。
应用客户端容器是由一组Java类和必须的文件组成,它同客户端应用一起运行在客户端的Java虚拟机中,管理应用客户端组件的执行。象其他Java EE应用组件一样,应用客户端的执行依赖于客户端容器提供的系统服务。客户端容器和金蝶Apusic应用服务器通讯使用RMI/IIOP。和其他服务器端的Java EE容器相比,应用客户端容器可以说是相对简单的容器。
应用客户端容器提供的系统服务有:
创建客户端运行环境,负责和应用服务器进行通讯。
提供JNDI包装,使客户端能够使用“java:”名字空间。如其他J2EE 组件,应用客户端使用JNDI查找EJB,访问对资源管理器的访问、服务器被管理对象等等,应用客户端使用java:JNDI名字空间来访问以上这些内容。
认证客户端。应用客户端容器自动完成JAAS用户认证。
另外,应用客户端不需要直接访问Java EE平台的事务功能。J2EE产品不需要提供JTA的UserTransaction对象给应用客户端使用。当然,应用客户端可以调用开始事务边界的EJB,并可使用JDBC API 提供的事务功能。但是当应用客户端调用EJB时开始了一个JDBC API 事务,事务环境不会传播到EJB 服务器。
应用客户端拥有所有的Java 2 Standard Edition 平台功能,每个应用客户端在客户端的Java虚拟机中运行。通过设置应用客户端JAR 文件中的manifest 文件的Main-Class属性,指定JAR文件中的Java类文件,运行时虚拟机查找Main-Class属性指定的类文件,执行其main方法(为准备容器环境,应用客户端容器在执行客户端程序之前运行, 安装SecurityManager,初始化名字服务客户端类库,等等)。
EJB容器可以有多种不同的实现方式,但每一个容器都支持标准的EJB客户端视图。当开发客户端时,开发者通过home接口获得对EJB的访问,然后通过调用定义在远程接口中的方法,使用业务逻辑。这个简单的编程模型被应用到所有的EJB客户端。
使用EJB Home和远程接口
范例程序说明了客户端程序必须包含的内容:
获得JNDI initial context。
使用initial context获得EJB Home引用。
通过调用EJB Home的create或find方法获得EJB实例引用。
访问EJB的业务逻辑方法。
使用JNDI查找和定位EJB组件的Home接口。下面的代码描述了定位EJB组件Home接口的步骤:
//创建initial contenxt Context initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/Hello"); HelloHome home = (HelloHome)PortableRemoteObject.narrow(objref,HelloHome.class);
客户端调用HelloHome对象的create方法创建EJB实例。create方法返回Hello类型的对象。远程接口Hello定义了提供给客户端调用的EJB业务方法。
Hello hello = home.create();
应用客户端被打包成JAR文件并且包含部署描述文件和MANIFEST.MF文件。部署描述文件是一个名为application-client.xml的xml文件,用于描述应用客户端所引用的EJB和外部资源。
application-client.xml文件必须符合application-client_1_4.xsd文档类型声明,并在文件中指定正确的schema:
version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd"
范例程序的客户端部署描述文件为,其中定义了EJB引用:
<?xml version="1.0" encoding="UTF-8"?> <application-client version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd"> <display-name>AppClient</display-name> <ejb-ref> <ejb-ref-name>ejb/Hello</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>samples.ejb.HelloHome</home> <remote>samples.ejb.HelloHome</remote> </ejb-ref> </application-client>
应用客户端开始执行MANIFEST.MF文件中Main-Class属性指定的类的main方法,例如:
Manifest-Version: 1.0 Created-By: Apache Ant 1.5.1 Main-Class: samples.client.Client
应用客户端JAR文件结构如下图:
应用客户端JAR文件结构
首先将应用客户端JAR文件和EJB JAR文件打包成J2EE应用,部署到Apusic应用服务器上。详细步骤请参考第 48.4 节 “打包和部署Java EE应用””。
然后使用Apusic提供的ejbGen工具生成可独立运行的应用客户端JAR文件:
java -classpath %apusic_home%/lib/apusic.jar com.apusic.tools.ejbgen.Main sample.ear appclient.jar
最后,在客户端容器中运行应用客户端:
java -classpath %apusic_home%/lib/apusic.jar -Djava.security.auth.login.config==login.conf com.apusic.client.Main -jar appclient.jar
![]() | 注意 |
---|---|
应用客户端运行在客户端容器中,会自动使用JAAS用户认证,因此需要提供LoginModules配置文件。配置文件中LoginModule的名字必须为“client”。客户端容器会自动使用名字为“client”的LoginModule进行JAAS用户认证。 如果使用apclient启动客户端容器,可以指定url参数,格式为:iiop://user:password@host:port,则不会弹出登录窗口。apclient使用$APUSIC_HOME/config/clientauth.cfg作为登录配置文件。也可以指定-noauth参数,以匿名身份访问服务器。 |
客户端可以不使用应用客户端容器,在获得初始化context时需要指定java.naming.factory.initial和java.naming.provider.url:
//设置初始化属性 Properties env = new Properties(); env.put("java.naming.factory.initial","com.apusic.naming.jndi.CNContextFactory"); env.put("java.naming.provider.url", "iiop://localhost:6888"); //获得 initial context Context initial = new InitialContext(env); //定位Home接口 Object objref = initial.lookup("ejb/appclientsample");
定位Home接口使用的JNDI名称为部署EJB时指定的JNDI名称。
![]() | 注意 |
---|---|
初始化context factory的类名为: com.apusic.naming.jndi.CNContextFactory Provider URL的格式为: iiop://<host>:<port> |