appfuse学习笔记

从 http://ant.apache.org下载最新版的 Ant,并解压缩到任意目录下。AppFuse 要求的最低版本是 1.6.2,本文采用的是 1.6.5。设置 ANT_HOME 指向 Ant 所在的目录,并在 PATH 中添加 %ANT_HOME%/bin。另外,要拷贝一个 junit.jar 到 %ANT_HOME%/lib 下,如果 lib 下没有 junit.jar,AppFuse 的脚本在运行时会给出警告信息。junit.jar 可以从 http://www.junit.org 获得,也可以从 %AppFuse%/lib/junit3.8.1 目录下获得。

本文的 AppFuse 安装在 "c:/opt" 下面。打开命令行控制台,进入 "c:/opt/appfuse",运行 “ant new”,为简单起见,所有参数选用默认值,

导入eclipse

去除了build中的源build/dao/gen

修改ant_home,注意要把junit.jar copy到lib下

打开ant视图,添加build文件

然后再打开properties.xml文件,修改里面的root用户的密码为你的mysql数据库访问时的密码。
<property name="database.host" value="localhost:3308"/>
<property name="database.admin.password" value="123456"/>
<property name="tomcat.home" value="D:/tbq/apache-tomcat-5.5.23"/>

然后在ant菜单界面中展开target列表,选择,setup目录安装所有装备工作,

AppFuse 预定义了两个用户:mraible 和 tomcat,密码都是 tomcat。mraible 属于管理员角色(能够管理用户信息),tomcat 属于普通用户角色。

或许此时,你已惊奇地发现,自己不过只运行了一次 Ant 脚本,但是系统已经拥有“用户管理”、“邮件”、“文件上传” 等功能 -- 这就是 AppFuse “开箱即用”的优势。接下来让我们开始开发前述的应用示例。

导入c:/opt/myapp/extras/appgen/build.xml
AppFuse 自带了一个代码生成工具 -- AppGen,它位于 c:/opt/myapp/extras/appgen 目录下面。AppGen 可以生成绝大部分我们需要的代码,比如 dao 类,service 类,菜单、增删改的 web 页面、配置文件、样本数据,等等。AppGen 利用 XDoclet 生成代码,因此可以在 extras/appgen/src 看到很多 .xdt 文件,这些就是 XDoclet 的模版定义文件。如果你希望自己编写 dao 和 service 类,就运行“install”这个 target,否则就用 “install-detailed” ,它可以帮你搞定一切。下面就让我们来运行 “install-detailed” 生成代码。在 c:/opt/myapp/extras/appgen 下运行 “ant install-detailed”。

生成Employee.hbm.xml有问题,路径不对
copy Employee.hbm.xml 到src/dao/org.appfuse.hr.model

不过,AppFuse 并不知道开发者需要加载哪些 hbm 文件,所以要手工将 Employee.hbm.xml 文件添加到配置文件中:打开 applicationContext-hibernate.xml,在 “sessionFactory” 的 bean 声明中,找到 “mappingResources” 属性的定义,增加 “<value>org/appfuse/hr/model/Employee.hbm.xml</value>”。

在 c:/opt/myapp 下运行 “ant deploy”。打开 “http://localhost:8080/myapp”,用 mraible/tomcat 登录,“Employee List” 已经被添加到菜单里了。
这个时候会清空数据库记录

   
   
文档选项
    将此页作为电子邮件发送   

将此页作为电子邮件发送
       

样例代码


级别: 中级

沈 锐 (shenrui@cn.ibm.com), 软件工程师, IBM CSDL

2006 年 10 月 19 日

    本文以一个 J2EE 开发者的角度,借助一个简单的应用示例,在融合了个人经验的基础上介绍了如何用 AppFuse 一步步地构建 J2EE 项目。通过阅读本文,读者不仅能够学会用 AppFuse 进行开发,而且能够充分体会到 AppFuse 提供的“快速开发”的优越性。

关于 AppFuse 的特性、架构以及为什么要使用 AppFuse,AppFuse 的创始人 Matt Raible 在 《使用 AppFuse 的七个理由》一文中已经做了很详尽的阐述,这里就不再赘言。本文将着力于实践,即如何运用 AppFuse 开发 J2EE 应用。

使用 AppFuse,你需要对 Ant 有一些基本的了解,比如什么叫 target、什么是 build.xml 以及如何运行 Ant,等等。如果你现在还不知道 Ant 是什么,就需要找些相关资料学习一下。下表列出了本文中用到的也是较为常用的 AppFuse 的 target:

表 1. Ant 中常用的 AppFuse target
target    说明    所在文件
new    这个 target 是使用 AppFuse 必须要用到的,它用来在 AppFuse 同级的目录下创建一个新项目。创建过程是交互式的,会让用户输入项目名称、数据库名称以及根包路径。    AppFuse 安装目录下的 build.xml
setup    用于初始化一个新的项目,它包含了从数据库创建、Tomcat 设置到 war 文件的生成和部署等一系列操作。    项目根目录下的 build.xml
deploy    如果你修改的代码不涉及到数据库的更改,那么可以使用这个 target,因为它只负责生成并重新部署 war 包。    项目根目录下的 build.xml
setup-db    如果你只是要对数据库进行更改,使用这个 target。比如,重新创建数据库,重新加载样本数据等操作。    项目根目录下的 build.xml
install    AppGen 的 target。如果你不希望使用 AppGen 帮你生成 dao 类和 service 类以及其他的代码,就使用这个 target。    extras/appgen 目录下的 build.xml
install-detailed    AppGen 的 target。如果你希望使用 AppGen 帮你生成所有代码,就使用这个 target。    extras/appgen 目录下的 build.xml

本文将按如下顺序展开叙述:

    * 示例介绍
    * 搭建开发环境
    * 新建项目
    * 创建数据库表
    * 用 AppGen 生成代码
    * 根据项目需求调整代码
    * 其他功能
          o 语言国际化
          o 页面布局和样式
          o 系统安全
          o 事务控制
          o 日志
          o 邮件
          o 缓存





    回页首


示例介绍

本文的示例实现对员工信息的增删查改等基本功能。用 Tapestry 实现表示层,用 Hibernate 开发持久层,用 Spring 提供事务控制等跨模块服务,并用 Acegi 进行安全管理。本示例只用到一个域模型:Employee,下面是它的 UML 图。

图 1. Employee UML 图
Employee UML 图




    回页首


搭建开发环境

本文的代码开发平台采用的是 Windows 操作系统,因此,以下环境设置也是针对 Windows 操作系统的。

    * 从 AppFuse 下载页面 下载 appfuse-tapestry-1.9.3-src.zip,并解压缩在任意目录下。这个 zip 已经定制了使用 Tapestry 作为表现层的实现框架,因而使用起来较为直接。
    * 从 http://java.sun.com 下载最新的 JDK,并安装或解压缩到任意目录下。本文采用 JDK 1.5.0。设置环境变量 JAVA_HOME 指向 JDK 所在的目录,并在 PATH 中添加 %JAVA_HOME%/bin。
    * 从 http://jakarta.apache.org/tomcat 下载最新版的 Tomcat,并安装或解压缩到任意目录下。本文采用 Tomcat 5.5.17。设置环境变量 CATALINA_HOME 指向 Tomcat 的安装目录。
    * 从 http://ant.apache.org下载最新版的 Ant,并解压缩到任意目录下。AppFuse 要求的最低版本是 1.6.2,本文采用的是 1.6.5。设置 ANT_HOME 指向 Ant 所在的目录,并在 PATH 中添加 %ANT_HOME%/bin。另外,要拷贝一个 junit.jar 到 %ANT_HOME%/lib 下,如果 lib 下没有 junit.jar,AppFuse 的脚本在运行时会给出警告信息。junit.jar 可以从 http://www.junit.org 获得,也可以从 %AppFuse%/lib/junit3.8.1 目录下获得。
    * 从 http://www.mysql.com 下载最新版的 MySQL,并安装或解压缩到任意目录下。本文采用的是 5.0。
    * 从 http://www.eclipse.org 下载 Eclipse 3.1 或 3.2,安装到任意目录下。

AppFuse 的 Ant 脚本可以在命令行中运行,也可以在 Eclipse 里运行。有关如何在 Eclipse 里执行 Ant 脚本,请参考《用Eclipse开发AppFuse应用》。到此,我们已经为 AppFuse 开发应用准备好了环境,下面让我们开始使用 AppFuse 创建项目。




    回页首


新建项目

AppFuse 的便捷与强大之处在于它已经为我们提供了多种开源框架的集成,并且通过使用 Ant 将所有的构建过程自动化。另外,AppFuse 利用 XDoclet 能够为我们生成绝大多数重要的代码,例如 dao 类、service 类以及测试用例,等等,并且能够将大量的配置文件也一并生成好,从而极大地节省了开发人员的时间。

用 AppFuse 进行开发通常有三种模式:“自上而下”,“自下而上”以及“混合模式”。采用“自上而下”(由 Java 对象向数据库对象创建的过程)的方式固然比较符合“面向对象”的设计思维,但是为此要编写大量的 XDoclet 的 tag 也确是一件痛苦的事情。相比较而言,采用“自下而上”(由数据库对象生成 Java 对象的过程)就显得简单许多 -- 只需要提供数据库表结构。然而,对于较为复杂的系统,尤其是类之间具有大量的关联的情形,仍然需要采用“自上而下”的创建模式。因此,在实际的项目开发中,将两种模式进行混合使用比较常见,这也就是“混合”模式。本文采用“自下而上”的模式。

本文的 AppFuse 安装在 "c:/opt" 下面。打开命令行控制台,进入 "c:/opt/appfuse",运行 “ant new”,为简单起见,所有参数选用默认值,见图 2。

图 2. ant new -- 新建项目
ant new -- 新建项目

脚本运行成功后,新项目创建在 c:/opt/myapp 下(与 AppFuse 目录同级),myapp 是 AppFuse 默认的项目名称。将该项目导入到 Eclipse 中,并根据 《用Eclipse开发AppFuse应用》 进行必要的设置。以下是两个你可能需要进行的配置:

    * AppFuse 默认连接 MySQL 的用户名是 root,密码为空。如果你的 root 密码不是空,需要修改 C:/opt/myapp/build.properties 中的 database.admin.password 项,记得将注释去掉。
    * AppFuse 默认不是用 utf-8 创建数据库,如果你需要支持多语言,需要修改 C:/opt/myapp/metadata/sql/mysql-create.sql 中的创建数据库的语句,修改如下:

      清单 1. 创建数据库语句

      create database if not exists @DB-NAME@ CHARACTER SET utf8 COLLATE utf8_general_ci;


      注:AppFuse 会在构建期将 @DB-NAME@ 替换成你指定的数据库名(本文中为“mydb”)。

在 c:/opt/myapp 下运行“ant setup test-all”。“setup” 完成了很多“设置”工作:创建数据库、构建 dao 和 serive 类、加载样本数据、创建 war 文件并部署到 tomcat,等等。“test-all” 运行所有的测试用例:对 dao,service 以及页面的测试。如果这个脚本运行成功,说明开发环境一切就绪。这时,启动 Tomcat,通过访问 http://localhost:8080/myapp 就能够看到 AppFuse 的登录界面了。AppFuse 预定义了两个用户:mraible 和 tomcat,密码都是 tomcat。mraible 属于管理员角色(能够管理用户信息),tomcat 属于普通用户角色。用 mraible 登录可以看到 图 3的界面。

图 3. AppFuse 的初始界面
AppFuse 的初始界面

或许此时,你已惊奇地发现,自己不过只运行了一次 Ant 脚本,但是系统已经拥有“用户管理”、“邮件”、“文件上传” 等功能 -- 这就是 AppFuse “开箱即用”的优势。接下来让我们开始开发前述的应用示例。




    回页首


创建数据库表

在 mydb 数据库中执行如下语句创建 employee 表:

清单 2. 创建 employee 语句

CREATE TABLE `employee` (
`id` bigint(20) NOT NULL auto_increment,
`code` varchar(10) NOT NULL,
`dept` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`status` varchar(10) NOT NULL,
`telephone` varchar(20) default NULL,
`title` varchar(50) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
             






    回页首


用 AppGen 生成代码

AppFuse 自带了一个代码生成工具 -- AppGen,它位于 c:/opt/myapp/extras/appgen 目录下面。AppGen 可以生成绝大部分我们需要的代码,比如 dao 类,service 类,菜单、增删改的 web 页面、配置文件、样本数据,等等。AppGen 利用 XDoclet 生成代码,因此可以在 extras/appgen/src 看到很多 .xdt 文件,这些就是 XDoclet 的模版定义文件。如果你希望自己编写 dao 和 service 类,就运行“install”这个 target,否则就用 “install-detailed” ,它可以帮你搞定一切。下面就让我们来运行 “install-detailed” 生成代码。在 c:/opt/myapp/extras/appgen 下运行 “ant install-detailed”。

清单 3. 运行 install-detailed

                ...
[input] Would you like to generate code from a table or POJO? (table,pojo)
table
[input] What is the name of your table (i.e. person)?
employee
[input] What is the name, if any, of the module for your table (i.e. organization)?
hr
...


前两个问题都很直观:选择从 table 生成代码,表名是 employee。第三个问题是让用户输入使用的模块名,如果你希望 AppFuse 帮你按模块生成代码的话,就需要输入一个模块名称。这里,我们输入“hr”。如果运行成功,在 Eclipse 中会看到如下的目录结构:

图 4. “install-detailed” 执行后的 Eclipse
“install-detailed” 执行后的 Eclipse

表 2 列出了 "install-detailed" 生成的主要文件。

表 2. "install-detailed" 生成的主要文件列表
文件    说明
myapp/src/dao/org/appfuse/dao/hibernate/applicationContext-hibernate.xml    在其中增加了 employeeDao 的声明
myapp/src/dao/org/appfuse/hr/model/Employee.java    Employee 类 -- Java Bean
myapp/build/dao/gen/org/appfuse/hr/model/Employee.hbm.xml    Employee 类的 Hibernate 映射文件
myapp/src/dao/org/appfuse/hr/dao/EmployeeDao.java    定义关于 employee 的 dao 层的操作
myapp/src/dao/org/appfuse/hr/dao/hibernate/EmployeeDaoHibernate.java    EmployeeDao 的 Hibernate 实现类
myapp/src/service/org/appfuse/service/applicationContext-service.xml    在其中增加了employeeManager的声明
myapp/src/service/org/appfuse/hr/service/EmployeeManager.java    定义关于 employee 的 service 层的操作
myapp/src/service/org/appfuse/hr/service/impl/EmployeeManagerImpl.java    EmployeeManager 的实现类
myapp/src/web/org/appfuse/hr/webapp/action/EmployeeForm.java    employee 的添加/修改页面对应的 tapestry 类
myapp/src/web/org/appfuse/hr/webapp/action/EmployeeList.java    employee 的列表页面对应的 tapestry 类
myapp/test/dao/org/appfuse/hr/dao/EmployeeDaoTest.java    employee dao 类的测试用例
myapp/test/service/org/appfuse/hr/dao/EmployeeManagerTest.java    employee service 类的测试用例
myapp/test/web/org/appfuse/hr/webapp/action/EmployeeFormTest.java    employee 添加/修改页面类的测试用例
myapp/test/web/org/appfuse/hr/webapp/action/EmployeeFormTest.java    employee 列表页面类的测试用例
myapp/web/pages/hr/employeeForm.html    employee 添加/修改页面 html 模版文件
myapp/web/pages/hr/employees.html    employee 列表页面 html 模版文件
myapp/web/pages/hr/employeeForm.page    employee 添加/修改页面规格文件
myapp/web/pages/hr/employees.page    employee 列表页面规格文件

不过,AppFuse 并不知道开发者需要加载哪些 hbm 文件,所以要手工将 Employee.hbm.xml 文件添加到配置文件中:打开 applicationContext-hibernate.xml,在 “sessionFactory” 的 bean 声明中,找到 “mappingResources” 属性的定义,增加 “<value>org/appfuse/hr/model/Employee.hbm.xml</value>”。

清单 4. applicationContext-hibnerate.xml 中添加 Employee.hbm.xml

                ...
<beans>
    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>org/appfuse/hr/model/Employee.hbm.xml</value>
                <value>org/appfuse/model/Role.hbm.xml</value>
                <value>org/appfuse/model/User.hbm.xml</value>
            </list>
        </property>
...


在 c:/opt/myapp 下运行 “ant deploy”。打开 “http://localhost:8080/myapp”,用 mraible/tomcat 登录,“Employee List” 已经被添加到菜单里了。

图 5. myapp 的原始主页面
myapp 的原始主页面

点击 “Employee List” 链接,进入“员工信息列表”页面。

图 6. myapp 的原始员工信息列表页面
myapp 的原始员工信息列表页面

点击“添加”按钮或点击任意一行数据,进入“员工信息添加/修改/删除”页面。

图 7. myapp 的原始员工信息添加/修改/删除页面
myapp 的原始员工信息添加/修改/删除页面

不难看出,虽然 AppFuse 帮我们生成了页面,但是这些页面并非那么“理想”,我们仍然需要根据实际的需求做些调整。




    回页首


根据项目需求调整代码

在本文中,做了如下代码修改:

    * 将所有页面文字翻译成中文:AppFuse 中用到的所有 Resource Bundle 文件位于 myapp/web/WEB-INF/classes 目录下(以ApplicationResources开头的properties文件)。更改 ApplicationResources_zh_CN.properties 的文件编码方式为“UTF-8”。然后,把 ApplicationResources.properties 中 “# -- Employee-START” 和 “# -- Employee-END” 之间的项拷贝到 ApplicationResources_zh_CN.properties 中,并逐项翻译成中文。AppFuse 会在脚本运行的时候自动用 native2ascii 进行编码转换。另外,AppFuse 默认对 “button.done” 的翻译是“做”,这不太合适,所以改为“完成”。
    * 在“员工信息列表页面”去掉了 id 列,并调整了列的顺序:只要修改 employees.html 就可以。
    * 在“员工信息添加/修改/删除页面”,将“所在部门”、“职位”、“状态”改为下拉列表:需要修改 employeeForm.html、employeeForm.page、EmployeeForm.java。用 PropertySelection 组件实现下拉列表,用 Resource Bundle 文件定义真正显示的选项文本。
    * 增加了一个“人事管理”的角色,用来执行员工信息管理的权限控制:具体介绍见“系统安全”。
    * 添加了一个新的主题 “mytheme”(只是更改了界面的颜色):具体介绍见“页面布局和样式”。

应用了上述修改后,在 c:/opt/myapp 中运行 “ant deploy” 重新打包整个项目并发布。以下是修改后的界面截图   
   
文档选项
    将此页作为电子邮件发送   

将此页作为电子邮件发送
       

样例代码


级别: 中级

沈 锐 (shenrui@cn.ibm.com), 软件工程师, IBM CSDL

2006 年 10 月 19 日

    本文以一个 J2EE 开发者的角度,借助一个简单的应用示例,在融合了个人经验的基础上介绍了如何用 AppFuse 一步步地构建 J2EE 项目。通过阅读本文,读者不仅能够学会用 AppFuse 进行开发,而且能够充分体会到 AppFuse 提供的“快速开发”的优越性。

关于 AppFuse 的特性、架构以及为什么要使用 AppFuse,AppFuse 的创始人 Matt Raible 在 《使用 AppFuse 的七个理由》一文中已经做了很详尽的阐述,这里就不再赘言。本文将着力于实践,即如何运用 AppFuse 开发 J2EE 应用。

使用 AppFuse,你需要对 Ant 有一些基本的了解,比如什么叫 target、什么是 build.xml 以及如何运行 Ant,等等。如果你现在还不知道 Ant 是什么,就需要找些相关资料学习一下。下表列出了本文中用到的也是较为常用的 AppFuse 的 target:

表 1. Ant 中常用的 AppFuse target
target    说明    所在文件
new    这个 target 是使用 AppFuse 必须要用到的,它用来在 AppFuse 同级的目录下创建一个新项目。创建过程是交互式的,会让用户输入项目名称、数据库名称以及根包路径。    AppFuse 安装目录下的 build.xml
setup    用于初始化一个新的项目,它包含了从数据库创建、Tomcat 设置到 war 文件的生成和部署等一系列操作。    项目根目录下的 build.xml
deploy    如果你修改的代码不涉及到数据库的更改,那么可以使用这个 target,因为它只负责生成并重新部署 war 包。    项目根目录下的 build.xml
setup-db    如果你只是要对数据库进行更改,使用这个 target。比如,重新创建数据库,重新加载样本数据等操作。    项目根目录下的 build.xml
install    AppGen 的 target。如果你不希望使用 AppGen 帮你生成 dao 类和 service 类以及其他的代码,就使用这个 target。    extras/appgen 目录下的 build.xml
install-detailed    AppGen 的 target。如果你希望使用 AppGen 帮你生成所有代码,就使用这个 target。    extras/appgen 目录下的 build.xml

本文将按如下顺序展开叙述:

    * 示例介绍
    * 搭建开发环境
    * 新建项目
    * 创建数据库表
    * 用 AppGen 生成代码
    * 根据项目需求调整代码
    * 其他功能
          o 语言国际化
          o 页面布局和样式
          o 系统安全
          o 事务控制
          o 日志
          o 邮件
          o 缓存





    回页首


示例介绍

本文的示例实现对员工信息的增删查改等基本功能。用 Tapestry 实现表示层,用 Hibernate 开发持久层,用 Spring 提供事务控制等跨模块服务,并用 Acegi 进行安全管理。本示例只用到一个域模型:Employee,下面是它的 UML 图。

图 1. Employee UML 图
Employee UML 图




    回页首


搭建开发环境

本文的代码开发平台采用的是 Windows 操作系统,因此,以下环境设置也是针对 Windows 操作系统的。

    * 从 AppFuse 下载页面 下载 appfuse-tapestry-1.9.3-src.zip,并解压缩在任意目录下。这个 zip 已经定制了使用 Tapestry 作为表现层的实现框架,因而使用起来较为直接。
    * 从 http://java.sun.com 下载最新的 JDK,并安装或解压缩到任意目录下。本文采用 JDK 1.5.0。设置环境变量 JAVA_HOME 指向 JDK 所在的目录,并在 PATH 中添加 %JAVA_HOME%/bin。
    * 从 http://jakarta.apache.org/tomcat 下载最新版的 Tomcat,并安装或解压缩到任意目录下。本文采用 Tomcat 5.5.17。设置环境变量 CATALINA_HOME 指向 Tomcat 的安装目录。
    * 从 http://ant.apache.org下载最新版的 Ant,并解压缩到任意目录下。AppFuse 要求的最低版本是 1.6.2,本文采用的是 1.6.5。设置 ANT_HOME 指向 Ant 所在的目录,并在 PATH 中添加 %ANT_HOME%/bin。另外,要拷贝一个 junit.jar 到 %ANT_HOME%/lib 下,如果 lib 下没有 junit.jar,AppFuse 的脚本在运行时会给出警告信息。junit.jar 可以从 http://www.junit.org 获得,也可以从 %AppFuse%/lib/junit3.8.1 目录下获得。
    * 从 http://www.mysql.com 下载最新版的 MySQL,并安装或解压缩到任意目录下。本文采用的是 5.0。
    * 从 http://www.eclipse.org 下载 Eclipse 3.1 或 3.2,安装到任意目录下。

AppFuse 的 Ant 脚本可以在命令行中运行,也可以在 Eclipse 里运行。有关如何在 Eclipse 里执行 Ant 脚本,请参考《用Eclipse开发AppFuse应用》。到此,我们已经为 AppFuse 开发应用准备好了环境,下面让我们开始使用 AppFuse 创建项目。




    回页首


新建项目

AppFuse 的便捷与强大之处在于它已经为我们提供了多种开源框架的集成,并且通过使用 Ant 将所有的构建过程自动化。另外,AppFuse 利用 XDoclet 能够为我们生成绝大多数重要的代码,例如 dao 类、service 类以及测试用例,等等,并且能够将大量的配置文件也一并生成好,从而极大地节省了开发人员的时间。

用 AppFuse 进行开发通常有三种模式:“自上而下”,“自下而上”以及“混合模式”。采用“自上而下”(由 Java 对象向数据库对象创建的过程)的方式固然比较符合“面向对象”的设计思维,但是为此要编写大量的 XDoclet 的 tag 也确是一件痛苦的事情。相比较而言,采用“自下而上”(由数据库对象生成 Java 对象的过程)就显得简单许多 -- 只需要提供数据库表结构。然而,对于较为复杂的系统,尤其是类之间具有大量的关联的情形,仍然需要采用“自上而下”的创建模式。因此,在实际的项目开发中,将两种模式进行混合使用比较常见,这也就是“混合”模式。本文采用“自下而上”的模式。

本文的 AppFuse 安装在 "c:/opt" 下面。打开命令行控制台,进入 "c:/opt/appfuse",运行 “ant new”,为简单起见,所有参数选用默认值,见图 2。

图 2. ant new -- 新建项目
ant new -- 新建项目

脚本运行成功后,新项目创建在 c:/opt/myapp 下(与 AppFuse 目录同级),myapp 是 AppFuse 默认的项目名称。将该项目导入到 Eclipse 中,并根据 《用Eclipse开发AppFuse应用》 进行必要的设置。以下是两个你可能需要进行的配置:

    * AppFuse 默认连接 MySQL 的用户名是 root,密码为空。如果你的 root 密码不是空,需要修改 C:/opt/myapp/build.properties 中的 database.admin.password 项,记得将注释去掉。
    * AppFuse 默认不是用 utf-8 创建数据库,如果你需要支持多语言,需要修改 C:/opt/myapp/metadata/sql/mysql-create.sql 中的创建数据库的语句,修改如下:

      清单 1. 创建数据库语句

      create database if not exists @DB-NAME@ CHARACTER SET utf8 COLLATE utf8_general_ci;


      注:AppFuse 会在构建期将 @DB-NAME@ 替换成你指定的数据库名(本文中为“mydb”)。

在 c:/opt/myapp 下运行“ant setup test-all”。“setup” 完成了很多“设置”工作:创建数据库、构建 dao 和 serive 类、加载样本数据、创建 war 文件并部署到 tomcat,等等。“test-all” 运行所有的测试用例:对 dao,service 以及页面的测试。如果这个脚本运行成功,说明开发环境一切就绪。这时,启动 Tomcat,通过访问 http://localhost:8080/myapp 就能够看到 AppFuse 的登录界面了。AppFuse 预定义了两个用户:mraible 和 tomcat,密码都是 tomcat。mraible 属于管理员角色(能够管理用户信息),tomcat 属于普通用户角色。用 mraible 登录可以看到 图 3的界面。

图 3. AppFuse 的初始界面
AppFuse 的初始界面

或许此时,你已惊奇地发现,自己不过只运行了一次 Ant 脚本,但是系统已经拥有“用户管理”、“邮件”、“文件上传” 等功能 -- 这就是 AppFuse “开箱即用”的优势。接下来让我们开始开发前述的应用示例。




    回页首


创建数据库表

在 mydb 数据库中执行如下语句创建 employee 表:

清单 2. 创建 employee 语句

CREATE TABLE `employee` (
`id` bigint(20) NOT NULL auto_increment,
`code` varchar(10) NOT NULL,
`dept` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`status` varchar(10) NOT NULL,
`telephone` varchar(20) default NULL,
`title` varchar(50) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
             






    回页首


用 AppGen 生成代码

AppFuse 自带了一个代码生成工具 -- AppGen,它位于 c:/opt/myapp/extras/appgen 目录下面。AppGen 可以生成绝大部分我们需要的代码,比如 dao 类,service 类,菜单、增删改的 web 页面、配置文件、样本数据,等等。AppGen 利用 XDoclet 生成代码,因此可以在 extras/appgen/src 看到很多 .xdt 文件,这些就是 XDoclet 的模版定义文件。如果你希望自己编写 dao 和 service 类,就运行“install”这个 target,否则就用 “install-detailed” ,它可以帮你搞定一切。下面就让我们来运行 “install-detailed” 生成代码。在 c:/opt/myapp/extras/appgen 下运行 “ant install-detailed”。

清单 3. 运行 install-detailed

                ...
[input] Would you like to generate code from a table or POJO? (table,pojo)
table
[input] What is the name of your table (i.e. person)?
employee
[input] What is the name, if any, of the module for your table (i.e. organization)?
hr
...


前两个问题都很直观:选择从 table 生成代码,表名是 employee。第三个问题是让用户输入使用的模块名,如果你希望 AppFuse 帮你按模块生成代码的话,就需要输入一个模块名称。这里,我们输入“hr”。如果运行成功,在 Eclipse 中会看到如下的目录结构:

图 4. “install-detailed” 执行后的 Eclipse
“install-detailed” 执行后的 Eclipse

表 2 列出了 "install-detailed" 生成的主要文件。

表 2. "install-detailed" 生成的主要文件列表
文件    说明
myapp/src/dao/org/appfuse/dao/hibernate/applicationContext-hibernate.xml    在其中增加了 employeeDao 的声明
myapp/src/dao/org/appfuse/hr/model/Employee.java    Employee 类 -- Java Bean
myapp/build/dao/gen/org/appfuse/hr/model/Employee.hbm.xml    Employee 类的 Hibernate 映射文件
myapp/src/dao/org/appfuse/hr/dao/EmployeeDao.java    定义关于 employee 的 dao 层的操作
myapp/src/dao/org/appfuse/hr/dao/hibernate/EmployeeDaoHibernate.java    EmployeeDao 的 Hibernate 实现类
myapp/src/service/org/appfuse/service/applicationContext-service.xml    在其中增加了employeeManager的声明
myapp/src/service/org/appfuse/hr/service/EmployeeManager.java    定义关于 employee 的 service 层的操作
myapp/src/service/org/appfuse/hr/service/impl/EmployeeManagerImpl.java    EmployeeManager 的实现类
myapp/src/web/org/appfuse/hr/webapp/action/EmployeeForm.java    employee 的添加/修改页面对应的 tapestry 类
myapp/src/web/org/appfuse/hr/webapp/action/EmployeeList.java    employee 的列表页面对应的 tapestry 类
myapp/test/dao/org/appfuse/hr/dao/EmployeeDaoTest.java    employee dao 类的测试用例
myapp/test/service/org/appfuse/hr/dao/EmployeeManagerTest.java    employee service 类的测试用例
myapp/test/web/org/appfuse/hr/webapp/action/EmployeeFormTest.java    employee 添加/修改页面类的测试用例
myapp/test/web/org/appfuse/hr/webapp/action/EmployeeFormTest.java    employee 列表页面类的测试用例
myapp/web/pages/hr/employeeForm.html    employee 添加/修改页面 html 模版文件
myapp/web/pages/hr/employees.html    employee 列表页面 html 模版文件
myapp/web/pages/hr/employeeForm.page    employee 添加/修改页面规格文件
myapp/web/pages/hr/employees.page    employee 列表页面规格文件

不过,AppFuse 并不知道开发者需要加载哪些 hbm 文件,所以要手工将 Employee.hbm.xml 文件添加到配置文件中:打开 applicationContext-hibernate.xml,在 “sessionFactory” 的 bean 声明中,找到 “mappingResources” 属性的定义,增加 “<value>org/appfuse/hr/model/Employee.hbm.xml</value>”。

清单 4. applicationContext-hibnerate.xml 中添加 Employee.hbm.xml

                ...
<beans>
    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>org/appfuse/hr/model/Employee.hbm.xml</value>
                <value>org/appfuse/model/Role.hbm.xml</value>
                <value>org/appfuse/model/User.hbm.xml</value>
            </list>
        </property>
...


在 c:/opt/myapp 下运行 “ant deploy”。打开 “http://localhost:8080/myapp”,用 mraible/tomcat 登录,“Employee List” 已经被添加到菜单里了。

图 5. myapp 的原始主页面
myapp 的原始主页面

点击 “Employee List” 链接,进入“员工信息列表”页面。

图 6. myapp 的原始员工信息列表页面
myapp 的原始员工信息列表页面

点击“添加”按钮或点击任意一行数据,进入“员工信息添加/修改/删除”页面。

图 7. myapp 的原始员工信息添加/修改/删除页面
myapp 的原始员工信息添加/修改/删除页面

不难看出,虽然 AppFuse 帮我们生成了页面,但是这些页面并非那么“理想”,我们仍然需要根据实际的需求做些调整。




    回页首


根据项目需求调整代码

在本文中,做了如下代码修改:

    * 将所有页面文字翻译成中文:AppFuse 中用到的所有 Resource Bundle 文件位于 myapp/web/WEB-INF/classes 目录下(以ApplicationResources开头的properties文件)。更改 ApplicationResources_zh_CN.properties 的文件编码方式为“UTF-8”。然后,把 ApplicationResources.properties 中 “# -- Employee-START” 和 “# -- Employee-END” 之间的项拷贝到 ApplicationResources_zh_CN.properties 中,并逐项翻译成中文。AppFuse 会在脚本运行的时候自动用 native2ascii 进行编码转换。另外,AppFuse 默认对 “button.done” 的翻译是“做”,这不太合适,所以改为“完成”。
    * 在“员工信息列表页面”去掉了 id 列,并调整了列的顺序:只要修改 employees.html 就可以。
    * 在“员工信息添加/修改/删除页面”,将“所在部门”、“职位”、“状态”改为下拉列表:需要修改 employeeForm.html、employeeForm.page、EmployeeForm.java。用 PropertySelection 组件实现下拉列表,用 Resource Bundle 文件定义真正显示的选项文本。
    * 增加了一个“人事管理”的角色,用来执行员工信息管理的权限控制:具体介绍见“系统安全”。
    * 添加了一个新的主题 “mytheme”(只是更改了界面的颜色):具体介绍见“页面布局和样式”。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值