建立,打包,部署及运行Duke 银行应用程序
作者:Jimsons
目录
1. 准备工作...
2. 启动服务器...
2.1创建银行数据库...
2.2捕获数据库模式...
2.3创建JDBC数据源...
2.4 将用户和组添加到file域...
3. 编译Duke银行应用程序代码...
4. 打包并部署Duke银行应用程序...
4.1 打包企业Beans.
4.2 打包应用程序客户端...
4.3 打包Web客户端...
4.4 打包并部署应用程序...
5. 运行应用程序客户端Application Client
6. 运行Web客户端...
7. 关于例子源代码中的错误更正...
7.1 NextIdBean代码中的错误...
7.2 Web模块中的错误...
8. 参考资料...
1. 准备工作
假设你的计算机中已经安装了J2EE 1.4 SDK,在建立DUKE银行应用程序之前,你必须到http://java.sun.com/j2ee/1.4/download.html #tutorial下载j2eetutorial压缩包并将其解压缩,假定你解压的路径为<INSTALL>/j2eetutorial14,打开例子的配置文件<INSTALL>/j2eetutorial14/examples/common/build.properties
l 将j2ee.home的值设为你应用程序服务器(Application Server)的安装位置,例如你的应用程序服务器安装在C:/Sun/AppServer,那么你应该设置如下: j2ee.home=C:/Sun/AppServer
l 将j2ee.tutorial.home 的值设置为你j2eetutorial的安装位置,例如: j2ee.tutorial.home=C:/j2eetutorial14
l 假如你安装应用程序服务器的时候管理员的用户名不是用默认的admin,那你要将admin.user的值改为你设置的用户名
l 假如你安装应用程序服务器时不是用默认的8080端口,则要将domain.resources.port的值改为你设置的端口.
l 将<INSTALL>/j2eetutorial14/examples/common/admin-password.txt文件中AS_ADMIN_PASSWORD的值设为你安装应用程序服务器时设置的管理员密码,如: AS_ADMIN_PASSWORD=yourpassword
2. 启动服务器
你必须先启动PointBase数据库服务器并且向数据库中添加客户和帐号的资料,你还要向应用程序服务器中添加一些资源, 最后你才能开始打包,部署和运行例子.
2.1创建银行数据库
你必须先创建数据库并向数据表中输入数据,然后企业Bean才能从中读取或向其中写入数据,请根据以下步骤来创建数据表并输入数据:
1. 启动PointBase数据库服务器
2. 打开命令行,转到<INSTALL>/j2eetutorial14/examples/bank/目录下,执行命令asant create-db_common, 这条命令调用PointBase终端工具库执行<INSTALL>/j2eetutorial14/examples/bank/sql/create-table.sql中的SQL语句, 这些SQL语句的功能是先删除所有已经存在的表并创建新表并向表中插入数据, 因为第一次运行这些语句时这些表并不存在, 所以你会看到一些SQL错误信息,你可以忽略不理这些错误信息.
2.2捕获数据库模式
在创建表并输入数据之后,你可以捕获表间的结构并保存到一个模式文件中,请通过以下步骤来捕获模式:
1. 打开命令行并切换到<INSTALL>/j2eetutorial14/examples/bank/目录
2. 执行以下命令asant capture-db-schema , 执行此命令后生成模式文件<INSTALL>/j2eetutorial14/examples/bank/build/dukesbank.dbschema
2.3创建JDBC数据源
Duke银行的企业Bean用JNDI名jdbc/BankDB来引用数据库,请执行以下步骤:
1. 打开管理终端页面http://localhost:4848/asadmin
2. 展开JDBC分支,选择JDBC Resources, 选择 New
3. 将其命名为jdbc/BankDB并将它映射到 PointBasePool
2.4 将用户和组添加到file域
将用户和组添加到file安全域后,应用程序服务器就能判断哪些用户能访问Web客户端的企业Bean的方法和资源,添加的步骤如下:
1. 打开管理终端页面http://localhost:4848/asadmin
2. 展开Configuration分支并展开Security分支
3. 展开Realms分支并选中file域
4. 点击Manage Users并点击New
5. 根据下表输入Duke银行的用户和组
User
Password
Group
200
j2ee
bankCustomer
bankadmin
j2ee
bankAdmin
3. 编译Duke银行应用程序代码
打开命令行,转到<INSTALL>/j2eetutorial14/examples/bank/目录,执行命令asant build ,这个命令就编译了企业Bean,应用程序客户端和Web客户端的全部代码,编译后的代码位于<INSTALL>/j2eetutorial14/examples/bank/build目录下.
4. 打包并部署Duke银行应用程序
以下过程假设你对用部署工具打包企业Bean, 应用程序客户端和Web应用程序的过程都比较熟悉,下面介绍如何打包并部署Duke银行(如果你按照以下步骤做了之后,部署或运行此应用程序还存在问题,那你可以用我们在<INSTALL>/j2eetutorial14/examples/bank/provided-jars/ 目录下提供的EAR文件即打包好的文件来部署和运行这个例子)
4.1 打包企业Beans
1. 创建一个EJB JAR模块并命名为DukesBankEJBJAR ,将其保存到<INSTALL>/j2eetutorial14/examples/bank/目录下.
2. 添加<INSTALL>/j2eetutorial14/examples/bank/build/com/sun/ebank/目录下的ejb和util包, 还有 <INSTALL>/j2eetutorial14/examples/bank/build/目录下的dukesbank.dbschema文件.
3. 创建实体Beans(选择添加到DukesBankEJBJAR中)
a. 用企业Bean向导创建下面每个表格中的CMP2.0 (容器管理持久性) 企业bean:
AccountBean的设置如下表:
Setting
Value
Local Home Interface
LocalAccountHome
Local Interface
LocalAccount
Persistent Fields
accountId, balance, beginBalance, beginBalanceTimeStamp, creditLine, description, type
Abstract Schema Name
AccountBean
Primary Key Class
Existing field accountId
CustomerBean的设置如下表:
Setting
Value
Local Home Interface
LocalCustomerHome
Local Interface
LocalCustomer
Persistent Fields
city, customerId, email, firstName, lastName, middleInitial, phone, state, street, zip
Abstract Schema Name
CustomerBean
Primary Key Class
Existing field customerId
TxBean的设置如下表:
Setting
Value
Local Home Interface
LocalTxHome
Local Interface
LocalTx
Persistent Fields
amount, balance, description, timeStamp, txId
Abstract Schema Name
TxBean
Primary Key Class
Existing field txId
NextIdBean的设置如下表:
Setting
Value
Local Home Interface
LocalNextIdHome
Local Interface
LocalNextId
Persistent Fields
beanName, id
Abstract Schema Name
NextIdBean
Primary Key Class
Existing field beanName
4. 根据下表建立实体bean的关系:
Multi-plicity
Bean A
Field Referencing Bean B and Field Type
Bean B
Field Referencing Bean A and Field Type
*:*
AccountBean
customers, java.util.Collection
CustomerBean
accounts, java.util.
Collection
1:*
AccountBean
none
TxBean
account
b. 在Sun-specific SettingsàCMP Database 对话框
1. 将JNDI名字命名为jdbc/BankDB
2. 点击Create Database Mappings,选中Map to Tables in Database Schema File并从下拉列表中选择dukesbank.dbschema,如下图所示
3. 每选择一个企业bean,下方就会显示持久域的映射, 请确认那些域和关系.
c. 根据下表为finder设置EJB QL查询语句
Duke银行中的finder查询
Enterprise Bean
Method
EJB QL Query
AccountBean
findByCustomerId
select distinct object(a)
from AccountBean a, in (a.customers) as c
where c.customerId = ?1
CustomerBean
findByAccountId
select distinct object(c)
from CustomerBean c, in (c.accounts) as a
where a.accountId = ?1
CustomerBean
findByLastName
select object(c)
from CustomerBean c
where c.lastName = ?1
TxBean
findByAccountId
select object(t)
from TxBean t
where t.account.accountId = ?3
and (t.timeStamp >= ?1 and t.timeStamp <= ?2)
d. 在NextIdBean的Transaction标签中,将 NextIdBean.getNextId 方法的Transaction Attributes属性设置为Requires New.
5. 调用企业Bean向导创建下表中的stateful session beans(即有状态会话bean)
Session Bean
Home Interface
Remote Interface
Implementation Class
Account
ControllerBean
Account
ControllerHome
Account
Controller
AccountControllerBean
Customer
ControllerBean
Customer
ControllerHome
Customer
Controller
CustomerControllerBean
TxControllerBean
TxControllerHome
TxController
TxBean
a. 根据下表列出的添加session beans 到local entity beans 的EJB references即EJB引用.
EJB References in AccountControllerBean
Coded Name
EJB Type
Interfaces
Home Interface
Local Interface
Enterprise Bean Name
ejb/account
Entity
Local
Local
AccountHome
LocalAccount
AccountBean
ejb/
customer
Entity
Local
Local
CustomerHome
LocalCustomer
CustomerBean
ejb/nextId
Entity
Local
Local
NextIdHome
LocalNextId
NextIdBean
EJB References in CustomerControllerBean
Coded Name
EJB Type
Interfaces
Home Interface
Local Interface
Enterprise Bean Name
ejb/customer
Entity
Local
Local CustomerHome
Local
Customer
CustomerBean
ejb/nextId
Entity
Local
Local
NextIdHome
Local
NextId
NextIdBean
EJB References in TxControllerBean
Coded Name
EJB Type
Interfaces
Home Interface
Local Interface
Enterprise Bean Name
ejb/account
Entity
Local
Local
AccountHome
Local
Account
AccountBean
ejb/
tx
Entity
Local
Local
TxHome
LocalTx
TxBean
ejb/nextId
Entity
Local
Local
NextIdHome
Local
NextId
NextIdBean
b. 将所有session bean的Transaction Management设置为Container-Managed即容器管理
6. 保存这个模块
4.2 打包应用程序客户端
1. 调用 Application Client 向导
a. 创建一个应用程序客户端模块,将它命名为DukesBankACJAR并把它保存到<INSTALL>/j2eetutorial14/examples/bank/目录下
b. 添加<INSTALL>/j2eetutorial14/examples/bank/build/com/sun/ebank/目录下的appclient, util, ejb/exception包和 ejb/*/*Controller* 即home和远程接口文件(即AccountController, AccountControllerHome, CustomerController, CustomerControllerHome, TxController, TxControllerHome) 到JAR中.
c. 选择appclient.BankAdmin 作为应用程序客户端的main class (主类)
2. 根据下表添加对session bean的EJB 引用
Coded Name
EJB Type
Interface
JNDI Name of Session Bean
ejb/accountController
Session
Remote
AccountControllerBean
ejb/customerController
Session
Remote
CustomerControllerBean
3. 保存这个模块.
4.3 打包Web客户端
1. 通过Web Component向导创建一个web模块,命名为DukesBankWAR并保存到<INSTALL>/j2eetutorial14/examples/bank/目录下,选择Dispatcher 作为Servlet类,其它保持默认.
2. 添加以下内容到web模块中
a. 添加<INSTALL>/j2eetutorial14/examples/bank/build/com/sun/ebank/目录下的web, util, ejb/exception包和 ejb/*/*Controller* 即home和远程接口文件(即AccountController, AccountControllerHome, CustomerController, CustomerControllerHome, TxController, TxControllerHome) 到模块中.
b. 添加<INSTALL>/j2eetutorial14/examples/bank/build/目录下的template目录,所有的jsp页面,所有的WebMessages*.properties文件和tutorial-template.tld文件到模块中.
c. 在添加文件的对话框中将WebMessages*.properties文件从根目录拖到WEB-INF/classes目录下,如下图
3. 将context root 设置为 /bank
4. 打开Dispatcher组件的Aliases标签, 添加/accountHist, /accountList, /atm, /atmAck, /main, /transferAck, /transferFunds, and /logoff作为aliases
5. 添加下表列出的session bean对EJB 的引用
Coded Name
EJB Type
Interface
JNDI Name of Session Bean
ejb/accountController
Session
Remote
AccountControllerBean
ejb/customerController
Session
Remote
CustomerControllerBean
ejb/txController
Session
Remote
TxControllerBean
6. 在标签JSP property添加名为bank的组,这个组对应的URL pattern(URL模式)为*.jsp,添加/template/prelude.jspf 到include prelude 中
7. 在Context标签,添加参数名为javax.servlet.jsp.jstl.fmt.localizationContext,值为WebMessages.
8. 在Security标签添加安全控制
a. 选择Form Based作为user authentication方法,在authentication设置中将realm的值设置为file, login page (登录页) 设置为/logon.jsp, error page (错误页)设置为/logonError.jsp.
b. 添加一个security constraint和web resource collection,用deploytool提供的默认名称
c. 在web resource collection.中添加URL Patterns(URL模式): /main, /accountList, /accountHist, /atm, /atmAck, /transferFunds, 和 /transferAck
d. 选中HTTP方法POST和GET.
e. 添加安全角色(authorized role ) bankCustomer
9. 保存这个模块
4.4 打包并部署应用程序
1. 创建一个J2EE application(J2EE应用程序),将它命名为DukesBankApp,并保存到<INSTALL>/j2eetutorial14/examples/bank/目录下
2. 添加DukesBankACJAR应用程序客户端模块到DukesBankApp
3. 添加DukesBankEJBJAR即EJB模块到DukesBankApp
4. 添加DukesBankWAR即Web模块到DukesBankApp
5. 添加安全角色(security roles) 名为 bankAdmin 和 bankCustomer
6. 为企业bean添加以下的安全设置(security settings)
a. AccountControllerBean:在Security标签,将方法removeCustomerFromAccount, removeAccount, createAccount, 和 addCustomerToAccount的限制访问权限的安全角色为bankAdmin ;在General标签, 点击Sun-specific Settings,然后在弹出的对话框中点击IOR, 在Context对话框将Required设置为true, 将realm设置为file.
b. CustomerControllerBean: 在Security标签,将方法getCustomersOfAccount, createCustomer, getCustomersOfLastName, setName, removeCustomer, 和 setAddress的限制访问权限的安全角色为bankAdmin ;在General标签, 点击Sun-specific Settings,然后在弹出的对话框中点击IOR, 在Context对话框将Required设置为true, 将realm设置为file.
c. TxControllerBean:在Security标签,将方法getTxsOfAccount, makeCharge, deposit, transferFunds, withdraw, 和 makePayment的限制访问权限的安全角色为bankCustomer
7. 如果你还没有启动应用程序服务器(Application Server.)那你现在就启动它.
8. 将bankCustomer角色映射到bankCustomer组
9. 将bankAdmin角色映射到bankAdmin组
10. 保存这个应用程序模块
11. Deploy(部署)这个应用程序,在部署kesBankApp对话框选中Return Client Jar即返回客户端Jar选项.
12. 在deploytool中选中server,将右边出现的bank选中并启动它.
5. 运行应用程序客户端Application Client
请根据以下步骤来运行应用程序客户端:
1. 打开命令行,转到<INSTALL>/j2eetutorial14/examples/bank/目录下
2. 如果是要运行英文版本的客户端就输入以下命令:appclient -client DukesBankAppClient.jar
DukesBankAppClient.jar这个文件是你刚才部署时选中返回客户端JAR而返回的文件.
3. 如果想运行西班牙语版本的客户端则运行以下命令:
appclient -client DukesBankAppClient.jar es
4. 在弹出的登录框中,输入用户名bankadmin密码为 j2ee,然后你就可以看到以下的界面.
6. 运行Web客户端
请根据以下步骤来运行Web客户端
1. 请在浏览器中打开地址http://localhost:8080/bank/main ,如果查看西班牙版本的客户端则只需在浏览器的语言设置中更改.
2. 在登录页面,输入用户名200,密码j2ee并提交.
3. 当你选择Account List,则你会看到以下画面.
7. 关于例子源代码中的错误更正
7.1 NextIdBean代码中的错误
此错误会造成部署发生错误不能完成,将<INSTALL>/j2eetutorial14/examples/bank/src/com/sun/ebank/ejb/util/目录下的NextIdBean.java文件打开,找到下面这行代码
public Object ejbCreate() throws CreateException {
将方法ejbCreate()的返回类型由Object更改为String,再重新编译,并在deploytool中更新此文件,重新部署即可成功
7.2 Web模块中的错误
打开Web客户端,输入用户名密码然后提交可能会抛出javax.servlet.jsp.JspTagException错误,请根据以下步骤进行更正:
1. 用文本编辑器新建java文档命名为CustomerHackFilter,保存到<INSTALL>/j2eetutorial14/examples/bank/src/com/sun/ebank/web目录下,内容如下:
package com.sun.ebank.web;
import javax.servlet.*;
import javax.servlet.http.*;
import com.sun.ebank.util.Debug;
import com.sun.ebank.web.*;
import java.io.IOException;
/**
* this is a dumb hack. update 4 seems to broken unless a
* CustomerBean is placed in the request linked to the BeanManager.
* Naturally, we need to add a BeanManager to the session here,
* doing some of the work the dispatcher should have done.
*/
public class CustomerHackFilter implements Filter
{
private FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig)
throws ServletException
{
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest req, ServletResponse response,
FilterChain chain)
throws IOException,
ServletException
{
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession();
BeanManager beanManager =
(BeanManager) session.getAttribute("beanManager");
if (beanManager == null) {
Debug.print("hack - Creating bean manager.");
beanManager = new BeanManager();
session.setAttribute("beanManager", beanManager);
}
CustomerBean customerBean = new CustomerBean();
customerBean.setBeanManager(beanManager);
request.setAttribute("customerBean", customerBean);
Debug.print("hack - added customerBean to request");
chain.doFilter(request, response);
}
}
2. 重新编译源代码
3. 选中DukesBankWAR模块,编辑内容,找到com/sun/ebank/web/ CustomerHackFilter.class,将它添加到包中.
4. 选中DukesBankWAR模块,在Filter Mapping标签,点击Edit Filter List,在弹出的对话框中点击Add Filter,在Filter Class下拉列表中选中com.sun.ebank.web.CustomerHackFilter,Filter Name为CustomerHack,选择OK
5. 还是在这个标签在,点击Add,弹出 “Add Servlet Filter Mapping”,在Filter Name下拉列表中选CustomerHack,下面选中 “Filter this Servlet”,选OK,如下图.
6. 保存这个模块并重新部署运行即可修正错误
8. 参考资料
[1]. http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html/
[2]. http://docs.jboss.org/jbossas/getting_started/startguide40/
[3]. 飞思科技产品研发中心.JSP应用开发详解.电子工业出版社.2004.5