摘要
这一章将向你介绍如何开发、部署和运行一个简单的client-server应用程序,这个应用程序包括一个enterprise bean和两个客户端:一个J2EE应用程序客户端和一个由JSP页面组成的Web客户端。
(2002-08-23 11:00:15)
By Wing, 出处:处处
原著:Dale Green
这一章将向你介绍如何开发、部署和运行一个简单的client-server应用程序,这个应用程序包括一个enterprise bean和两个客户端:一个J2EE应用程序客户端和一个由JSP页面组成的Web客户端。
安装
在你开发示例应用程序之前,你必须首先参阅下面的说明。
获得示例代码
在j2eetutorial/examples/src/ejb/converter目录下有组件的源代码,这个目录会在你将指南的软件包进行解压时自动生成。如果你是在线阅读这个指南,你必须从下面这个地址下载这个软件包:
http://java.sun.com/j2ee/download.html#tutorial
获得构造工具(ant)
要建立示例代码,你必须安装J2EE SDK和ant,ant是一个方便的构造工具。有关ant的更多信息,请参看如何建立和运行示例程序。
检查环境变量
J2EE SDK和ant的安装说明书说明了如何设置需要的环境变量。根据表2-1检查环境变量是否正确设置。
表2-1需要的环境变量
环境变量:变量值
JAVA_HOME:J2SE SDK的安装位置。
J2EE_HOME:J2EE SDK的安装位置。
ANT_HOME:ant的安装位置。
PATH:需要包含J2EE SDK、J2SE和ant安装位置的bin目录。
启动J2EE服务器
要运行J2EE服务器,打开一个命令行窗口输入以下命令:
|
尽管verbose选项不是必须的。但是使用该选项可以便于进行调试。
要停止服务,输入下面命令:
|
启动部署工具
deploytool功能有两个模式:命令行和GUI。在这一章中我们主要针对GUI版本。要启动deploytool GUI,打开一个命令行窗口并输入下面命令:
|
按F1键,可以查阅工具的相关帮助。
创建 J2EE应用程序
示例应用程序包含三个J2EE组件:一个enterprise bean、一个J2EE应用程序客户端和一个Web组件。在建立组件之前,你需要建立一个新的名为ConverterApp的J2EE应用程序,并将其存储在一个名为ConverterApp.ear的EAR文件中。
1、在deploytool中,选择FileNewApplication。
2、点击Browse。
3、选择目录j2eetutorial/examples/src/ejb/converter。
4、输入文件名ConverterApp.ear。
5、点击New Application。
6、点击OK。
创建Enterprise Bean
一个enterprise bean就是一个服务器端的组件,它包含了一个应用程序的商业逻辑。在运行时,应用程序客户端通过调用enterprise bean的方法执行商业逻辑。在我们的例子中,enterprise bean是一个名为ConverterEJB的stateless session bean。ConverterEJB的源代码在j2eetutorial/examples/src/ejb/converter目录下。
编写Enterprise Bean
在这个例子中enterprise bean需要下面的代码:
1、Remote接口
2、Home接口
3、Enterprise bean类
编写Remote接口
一个remote接口定义了客户端需要调用的商业方法。这些商业方法是在enterprise bean的代码中实现的。Converter的remote接口的源代码如下:
|
编写Home接口
一个home接口定义了允许客户端创建、寻找和删除一个enterprise bean的方法。ConverterHome接口仅仅包含了一个创建方法,它返回一个remote接口类型的对象。下面是ConverterHome接口的源代码:
|
编写Enterprise Bean类
在这个示例中有一个名为ConverterBean的enterprise bean类。这个类实现了remote接口Converter中定义的两个商业方法: dollarToYen和yenToEuro。ConverterBean类的源代码如下:
|
编译源文件
现在我们开始准备编译remote接口(Converter.java)、home接口(ConverterHome.java)和enterprise bean类(ConverterBean.java):
1、在一个命令行窗口中,进入j2eetutorial/examples目录。
2、输入下面的命令:
|
这个命令对enterprise bean和J2EE应用程序客户端的源文件进行了编译。得到的class文件在j2eetutorial/examples/build/ejb/converter目录下(不是src目录)。有关ant的更多信息,请参看如何构建和运行这个示例。
注意:在编译代码时,上述的ant任务包含了在classpath中的j2ee.jar文件。这个文件在你安装的J2EE SDK的lib目录下。如果你想要用其它工具编译J2EE组件的源代码,必须首先确保classpath中包含了j2ee.jar文件。
对Enterprise Bean进行打包
要将一个enteprise bean打包,你必须运行deploytool中的New Enterprise Bean向导。在这一过程中,向导会执行下面的任务。
1、创建bean的部署描述
2、将部署描述和bean的类打包到一个EJB JAR文件中
3、将这个EJB JAR文件插入到应用程序的ConverterApp.ear文件中
在打包的过程中,你可以通过选择Tools->Descriptor Viewer查看部署描述。
要开始New Enterprise Bean向导,选择File->New->Enterprise Bean。向导会显示下面的对话框。
1、Introduction对话框
a、阅读有关向导功能的说明。
b、单击Next。
2、EJB JAR对话框
a、在Application按钮中选择Create New JAR File。
b、在组合框中选择ConverterApp。
c、在JAR显示命名区域,输入ConverterJAR。
d、单击Edit。
e、选择j2eetutorial/examples/build/ejb/converter目录。(如果converter目录的位置在多层子目录下,你可以简单地在起始目录中直接输入converter目录的绝对路径。)
f、选择下面的类并按Add:Converter.class、ConverterBean.class, and ConverterHome.class。 (你可能还需要将这些类文件拖动到Content文本区域中。)
g、单击OK。
h、单击Next。
3、综合对话框
a、在Bean类型下,选择Session单选按钮。
b、选择Stateless单选按钮。
c、在Enterprise Bean Class组合框中,选择ConverterBean。
d、在Enterprise Bean Name区域,输入ConverterEJB。
e、在Remote Home Interface组合框中,选择ConverterHome。
f、在Remote Interface组合框中,选择Converter。
g、单击Next。
4、事务管理对话框
你可以单击Finish跳过剩下的对话框。
创建J2EE应用程序客户端
一个J2EE应用程序客户就是用Java编程语言编写的一段程序。在运行时,客户端程序不是运行在J2EE服务器上,而是运行在虚拟机上。
在这个例子中的J2EE应用程序客户端需要两个不同的JAR文件。第一个JAR文件是客户端的J2EE组件。这个JAR文件包含了客户端的部署描述和它的类文件。当你运行New Application Client向导时,deploytool会自动建立JAR文件并将其存储到应用程序的EAR文件中。根据J2EE规则,这个JAR文件可以移植到任何J2EE服务器。
第二个JAR文件包含了客户端程序运行时所需要的stub类。这些stub类的存在使得客户端可以访问运行在J2EE服务器上的enterprise bean。因为第二个JAR文件并不完全遵守J2EE规范,它只能在J2EE SDK上执行。
J2EE应用程序客户端的源代码是j2eetutorial/examples/src/ejb/converter/ConverterClient.java。在编译源文件中你已经随同enterprise bean的代码一起对这个代码进行了编译。
编写J2EE应用程序客户端
ConverterClient.java的源代码阐明了一个enterprise bean的客户端所执行的基本任务:
1、查找home接口
2、创建一个enterprise bean的实例
3、调用一个商业方法
查找Home接口
ConverterHome接口定义了诸如create这样的生命周期方法。在ConverterClient可以调用create方法之前,它必须寻找并例示一个类型为ConverterHome的对象。这个过程可以分为四步。
1、创建一个初始化命名环境。
|
Context接口是Java命名目录接口(JNDI)的一部分。一个naming contex就是一系列命名与对象的绑定。一个与环境绑定的命名就是一个对象的JNDI name。
一个实现Context接口的InitialContext对象,提供了分辨命名的切入点。所有的命名操作都是相对于环境的。
2、获得应用程序客户端的命名环境的环境。
|
java:comp/env命名是绑定到ConverterClient组件的命名环境的环境。
3、检索绑定到命名ejb/SimpleConverter的对象。
|
ejb/SimpleConverter命名绑定到一个enterprise bean reference,这是一个enterprise bean的home的逻辑命名。在这种情况下,ejb/SimpleConverter命名指向ConverterHome对象。enterprise beans的命名必须在java:com/env/ejb子环境中。
4、细化ConverterHome对象的环境。
|
创建一个Enterprise Bean实例
要创建一个bean的实例,客户端需要调用ConverterHome上的create方法。create方法返回一个类型为Converter的对象。Converter的remote接口定义了客户端可以调用的bean的商业方法。当客户调用create方法时,EJB容器对bean进行实例化并调用ConverterBean.ejbCreate方法。客户端将采用下面的格式调用create方法:
|
调用一个商业方法
调用一个商业方法很简单--你只需要简单地调用Converter对象上的方法。EJB容器会调用相应的运行在服务器上的ConverterEJB实例的方法。客户端调用dollarToYen商业方法的代码如下:
|
ConverterClient的源代码
ConverterClient的全部源代码如下:
|
编译应用程序客户端
应用程序客户端文件与enterprise bean文件一起被编译,参见编译源文件。
对J2EE应用程序客户端进行打包
要将一个应用程序客户端组件进行打包,你需要运行deploytool的New Application Client向导。在这一过程中向导将执行以下任务。
1、创建应用程序客户端的部署描述
2、将部署描述和客户端文件装入一个JAR文件中
3、将这个JAR文件添加到应用程序的ConverterApp.ear文件中
在打包时,你可以通过选择Tools->Descriptor Viewer对部署描述进行预览。
要启动New Application Client向导,选择File->New->Application Client。向导将显示以下对话框。
1、Introduction对话框
a、阅读有关向导功能的说明。
b、单击Next。
2、JAR文件内容对话框
a、在组合框中选择ConverterApp。
b、单击Edit。
c、在可用文件中,找到j2eetutorial/examples/build/ejb/converter目录。
d、选择ConverterClient.class文件并单击Add。
e、单击OK。
f、单击Next。
3、综合对话框
a、在Main Class的组合框中,选择ConverterClient。
b、检查Display Name区域是否为ConverterClient。
c、在Callback Handler Class组合框中选择container-managed authentication。
d、单击Next。
e、单击Finish。
指定应用程序客户端的Enterprise Bean环境
在调用lookup方法时,ConverterClient会引用一个enterprise bean的home:
|
你可以根据以下步骤指定这个环境:
1、选择ConverterClient。
2、选择EJB Refs标签。
3、单击Add。
4、在Coded Name列,输入ejb/SimpleConverter。
5、在Type列,选择Session。
6、在Interfaces列,选择Remote。
7、在Home Interface列,输入ConverterHome。
8、在Local/Remote Interface列,输入Converter。
创建Web客户端
Web客户端包含在j2eetutorial/examples/src/ejb/converter/index.jsp这个JSP页面中。一个JSP页面就是一个基于文本的文档,它既可以包含可以用任何诸如HTML、WML和XML这样的其于文本的格式表示的静态模板数据;也可以包含用来构造动态内容的JSP元件。
编写Web客户端
定位home接口的语句(下面代码中黑体的部分)创建了一个enterprise bean的实例,然后使用几乎与J2EE应用程序客户端一样的途径来调用一个商业方法。仅仅是lookup方法的参数有所不同;有关使用不同的命名的原因我们将在指定JNDI命名中作详细讨论。
一个JSP页面的命令定义了客户端所需要的类(以<%@ %>符号引起的部分)。因为寻找home接口和创建enterprise bean只被执行一次,这个代码出现在JSP页面的一个包含了初始化方法jspInit的JSP申明(<%! %>符号引起的部分)中。在这个申明后面是一个标准的用来获取数据的HTML表单。这段脚本(<% %>符号引起的部分)从请示获得了一个参数并将其转换为double类型。最终,JSP表达式(<%= %>符号引起的部分)调用了enterprise bean的商业方法并将结果插入到返回客户端的数据流中。
|
编译Web客户端
J2EE服务器将对JSP格式的Web客户端自动进行编译。如果这个Web客户端是一个servlet,你可能需要自己进行编译。
将Web客户端打包
要将一个Web客户端打包,你需要运行deploytool的New Web Component向导。在这一过程中将执行下面的任务。
1、创建Web应用程序部署说明
2、将组件文件添加到一个WAR文件中
3、将这个WAR文件添加到应用程序的ConverterApp.ear文件中
在打包的过程中,你可以通过选择Tools->Descriptor Viewer对部署说明进行预览。
要启动New Web Component向导,你需要选择File->New->Web Component。这个向导将显示以下的对话框。
1、Introduction对话框
a、阅读有关向导功能的说明。
b、单击Next。
2、WAR文件对话框
a、选择Create New WAR File In Application。
b、在组合框中,选择ConverterApp。
c、在WAR Display Name区域,输入ConverterWAR。
d、单击Edit。
e、在可用文件中,选择j2eetutorial/examples/build/ejb/converter目录。
f、选择index.jsp并单击Add。
g、单击OK。
h、单击Next。
3、选择组件类型对话框
a、选择JSP按钮。
b、按Next。
4、组件综合属性对话框
a、在JSP文件名组合框,选择index.jsp。
b、单击Finish。
指定Web客户端的Enterprise Bean环境
在调用lookup方法时,Web客户端引用了一个enterprise bean的home:
|
你将按照以下步骤指定环境:
1、选择ConverterWAR。
2、选择EJB Refs标签。
3、单击Add。
4、在Coded Name列,输入ejb/TheConverter。
5、在Type列,选择Session。
6、在Interfaces列,选择Remote。
7、在Home Interface列,输入ConverterHome。
8、在Local/Remote Interface列,输入Converter。
指定JNDI命名
尽管J2EE应用程序客户端和Web客户端访问的是同一个enterprise bean,但是在代码中引用bean的home时是用的不同的命名。J2EE应用程序客户端使用ejb/SimpleConverter引用bean的home,而Web客户端使用ejb/TheConverter引用bean的home。这些环境作为调用lookup时使用的参数。为了lookup方法得到home对象,你必须映射环境到enterprise bean的JNDI命名。尽管这种映射增加了一个间接的层次,但是这种做法使得客户端和bean相对分离,使得使用J2EE组件装配应用程序更为简单。
要映射客户端的enterprise bean环境到bean的JNDI命名,需要遵循以下步骤:
1、选择ConverterApp。
2、选择JNDI Names标签。
3、要指定一个bean的JNDI命名,在Application表寻找ConverterEJB组件并在JNDI命名列中输入MyConverter。
4、为了映射环境,在References表的每一行的JNDI命名中输入MyConverter。
图2-1显示了在你执行了以上步骤后JNDI Names表的情况。
图2-1 ConverterApp JNDI命名
部署J2EE应用程序
现在J2EE应用程序的组件已经准备完毕,可以开始部署了。
1、选择ConverterApp应用程序。
2、选择Tools->Deploy。
3、在Introduction对话框,确认ConverterApp是否显示在部署的对象中以及目的服务器中是否显示的是localhost。
4、选择标签为Return Client Jar的检查框。
5、在显示的文本区域,输入ConverterAppClient.jar文件的全部路径名以保证其出现在j2eetutorial/examples/src/ejb/converter子目录中。ConverterAppClient.jar文件包含可以远程访问ConverterEJB的stub类。
6、单击Next.
7、在JNDI命名对话框,检查你输入的命名是否正确。
8、单击Next。
9、在WAR Context Root对话框的Context Root区域输入converter。当你运行Web客户端,converter将是URL的一部分。
10、单击Next。
11、在Review对话框,单击Finish。
12、在Deployment Progress对话框,当部署完成时单击OK。
运行J2EE应用程序客户端
要运行J2EE应用程序客户端,需要执行以下步骤。
1、在一个终端窗口,选择j2eetutorial/examples/src/ejb/converter目录。
2、检查目录中是否包含ConverterApp.ear和ConverterAppClient.jar文件。
3、设置APPCPATH环境变量为ConverterAppClient.jar。
4、输入以下命令(在同一行中):
|
5、在客户端容器提示你登录时,以guest作为用户名,以guest123作为口令。
6、在终端窗口,客户端显示以下内容:
|
运行Web客户端
要运行Web客户端,在浏览器的地址栏中输入以下URL。将<host>改为运行J2EE服务器的主机名。如果你的浏览器是运行在J2EE服务器所运行的同一台主机上,你可以将<host>改为localhost。
http://<host>:8000/converter
在输入域中输入100并单击Submit后,你应该可以看到如图2-2所示的页面。
图2-2 Converter Web客户端
修改J2EE应用程序
因为J2EE SDK主要是用来试验的,因此它支持反复地部署。一旦你对J2EE应用程序作了修改,你就必须重新部署应用程序。
修改一个类文件
要修改一个enterprise bean的类文件,你就必须修改源代码,对它重新编译并重新部署应用程序。例如,如果你要改变ConverterBean中的dollarToYen商业方法的汇率:
1、编辑ConverterBean.java。
2、通过输入ant converter重新编译ConverterBean.java。
3、在deploytool中,选择Tools->Update Files。
4、这时会出现一个显示已改变的文件的对话框。检查ConverterBean.class是否已被改变然后关闭这个对话框。
5、在确保标记为Save Object Before Deploying的单选框已被选中后选择Tools->Deploy。
你也可以通过选择Tools->Update And Redeploy来执行第4步和第5步。deploytool将使用新的文件取代ConverterApp.ear 中的旧的文件并重新部署应用程序。
增加一个文件
要向应用程序的EJB JAR或WAR中增加一个文件,执行以下几步:
1、选择JAR或WAR。
2、选择General标签。
3、单击Edit。
4、在可用文件中找到该文件并单击Add。
5、单击OK。
6、在main工具栏中,选择Tools->Update And Redeploy。
修改Web客户端
要修改Web客户端,执行以下几步:
1、编辑index.jsp。
2、执行ant converter以拷贝修改的文件到构造目录。
3、在deploytool中,选择Tools->Update Files。
4、这时会出现一个显示已改变的文件的对话框。检查index.jsp是否已被改变然后关闭这个对话框。
5、在确保标记为Save Object Before Deploying的单选框已被选中后选择Tools->Deploy。
你也可以通过选择Tools->Update And Redeploy来执行第4步和第5步。deploytool将使用新的文件取代ConverterApp.ear 中的旧的文件并重新部署应用程序。
修改一个部署设置
要修改ConverterApp的一个部署设置,你需要编辑标签面板上的适当字段并重新部署应用程序。例如,要将ConverterBean的JNDI命名从ATypo改为MyConverter,你需要执行以下几步:
1、在deploytool,选择ConverterApp。
2、选择JNDI Names标签。
3、在JNDI Name中输入MyConverter。
4、在main工具栏中,选择FileSave。
5、选择Tools->Update And Redeploy.
常见问题及其解决办法
不能启动J2EE服务器
命名目录服务端口冲突
症状:当你使用-verbose选择启动J2EE服务器时,显示以下信息:
|
解决办法:其它程序使用了1050端口。如果J2EE服务已经运行了,你可以通过输入 j2ee -stop停止这个服务。如果其它程序使用了这个端口,你可以通过修改你的J2EE SDK安装的config/orb.properties文件以改变默认端口(1050)。
有关默认端口号的更多信息,请参看下载J2EE SDK时同时提供的配置向导。
Web服务端口冲突
症状:当你使用-verbose选项启动J2EE服务时,显示以下信息:
|
解决办法:其它程序使用了端口8000。你可以通过修改你的J2EE SDK安装的config/orb.properties文件以改变默认端口(8000)。
错误的XML解析
症状:当你使用-verbose选项启动J2EE服务时,显示以下信息:
|
解决办法:从你的J2SE安装目录中删除jre/lib/jaxp.properties文件。
编译错误
ant不能找到构造文件
症状:当你输入ant converter后,显示以下信息:
|
解决办法:在运行ant前,先转到j2eetutorial/examples/src目录。如果你想要在当前目录中运行ant,你必须在命令行指定构造文件。例如,在窗口中你需要在同一行中输入以下命令:
|
编译器不能解析符号
症状:当你输入ant converter后,编译器报告很多错误,其中包括:
|
解决办法:确保你是否已经正确配置了J2EE_HOME环境变量。详细信息请参阅检查环境变量。
在你运行客户端后ant 1.4不能编译示例
症状:ant 1.4显示以下错误:
|
解决办法:使用ant的1.3版本。对于1.4版本,ant.bat脚本和J2EE SDK的脚本都使用了JAVACMD环境变量。而SDK的runclient.bat脚本可能对JAVACMD进行了设置,这就造成了ant.bat的问题。
部署错误
在你的类路径中错误的XML解析
症状:显示以下错误:
|
解决办法:从你的J2SE安装目录的jre/lib/ext子目录下删除jaxp.jar文件。这个JAR文件包含了和J2EE服务器不兼容的XML解析程序。如果你没有一个jaxp.jar文件,你的类路径可能会引用一个Tomcat安装的XML程序。在这种情况下,你需要从你的类路径中删除这个环境。
远程Home接口被指定为一个本地Home接口
症状:显示以下错误:
|
解决办法:从EAR文件中删除这个enterprise bean(EditDelete)并使用New Enterprise Bean向导建立一个新的bean。在向导的综合对话框中,选择Remote Home Interface和Remote Interface组合框。
J2EE应用程序客户端运行错误
客户端抛出一个NoClassDefFoundError
症状:客户端报告以下例外:
|
解决办法:造成这个错误的原因是客户端不能找到ConverterAppClient.jar文件中的类。请认真检查你是否正确地按照运行J2EE应用程序客户端中的部署执行了。
客户端不能找到ConverterApp.ear
症状:客户端报告以下例外:
|
解决办法:认真检查ConverterApp.ear文件是否存在,并且为其指定了-client选项:
|
有关创建ConverterApp.ear文件的详细信息请参看创建J2EE应用程序和运行J2EE应用程序客户端。
客户端不能找到ConverterClient组件
症状:客户端显示以下信息:
|
解决办法:检查你是否已经建立了ConverterClient组件以及是否在runclient命令中指定了-name选项。有关建立ConverterClient组件的详细信息请参看将J2EE应用程序客户端打包。
登录失败
症状:在登录后,显示如下信息:
|
解决办法:在登录提示符后用户名输入guest,口令输入guest123。
J2EE应用程序未被部署
症状:客户端报告以下例外:
|
解决办法:部署应用程序,详细介绍请参看部署J2EE应用程序。
JNDI命名错误
症状:客户端报告以下例外:
|
解决办法:在标志为ConverterApp的JNDI命名面板中,检查ConverterBean的JNDI命名是否与ejb/SimpleConverter匹配。重新指定正确的JNDI命名并重新部署应用程序。
Web客户端运行错误
Web的URL环境不正确
症状:浏览器报告页面未找到(HTTP 404)。
解决办法:检查Web的URL环境(converter)是否与你在Component General Properties对话框中指定的匹配(参见将Web客户端打包)。在特别注意大小写的问题。
J2EE应用程序未被部署
症状:浏览器报告页面未找到(HTTP 404)。
解决办法:部署应用程序。
JNDI命名错误
症状:当你点击Web页面上的Submit按钮后,浏览器报告
|
解决办法:在标志为ConverterApp的JNDI命名面板中,检查ConverterBean的JNDI命名和ConverterWAR的JNDI命名是否匹配。重新指定正确的JNDI命名并重新部署应用程序。
校验工具发现的错误
校验工具(verifier)可以发现部署描述和方法特征之间的矛盾。这些矛盾常常会导致部署和运行时的错误。在deploytool中,你可以通过选择ToolsVerifier运行verifier的GUI版本。你也可以单独运行verifier的GUI版本或命令行版。更多的信息请参看附录B.
将你的EAR文件与我们的比较
对于这个例子的绝大部分,在下载的文件中包含了J2EE应用程序的EAR文件,它们位于j2eetutorial/examples/ears目录下。
其它错误
如果上面的这些建议都不能解决问题,你可能需要重新安装应用程序并通过运行cleanup脚本清除服务器中的存储内容。你当然还需要关闭并重新启动服务器:
|