AppFuse 是一个开放源码的目和应用程序,它用了?Java q_上构建的开放源码工h帮助我们快速而高效地开?Web 应用E序。我最初开发它是ؓ了减在为客h建新 Web 应用E序时所p的那些不必要的时间。从核心上来_AppFuse 是一个项目骨ӞcM于通过向导创徏?Web 目?IDE 所创徏的东ѝ当我们使用 AppFuse 创徏一个项目时Q它会提C我们将使用开放源码框Ӟ然后才创建项目。它使用 Ant 来驱动测试、代码生成、编译和部v。它提供了目录和包结构,以及开发基?Java 语言?Web 应用E序所需要的库?/p>
与大部分 “new project” 向导不同QAppFuse 创徏的项目从最开始就包含很多cd文g。这些文件用来实现特性,不过它们同时也会在您开发应用程序时被用作示例。通过使用 AppFuse 启动新项目,我们通常可以减少一C周的开发时间。我们不用担心如何将开放源码框枉|在一P因ؓq都已经完成了。我们的目都已提前配置来与数据库进 行交互,它会部v到应用服务器上,q对用户q行认证。我们不必实现安全特性,因ؓq都早已集成了?/p>
当我最初开?AppFuse Ӟ它只支持 Struts ?Hibernate。经q几q的努力Q我发现了比 Struts 更好?Web 框架Q因此我q添加了?Web 框架使用的选项。现在,AppFuse 可以支持 Hibernate ?iBATIS 作ؓ持久性框架。对? Web 框架来说Q我们可以?JavaServer FacesQJSFQ、Spring MVC、Struts、Tapestry ? WebWork?/p>
AppFuse 提供了很多应用程序需要的一些特性,包括Q?/p>
q种 “开即?#8221; 的功能是 AppFuse 与其?CRUD ?/em> 框架的区别之一QCRUD 取自创徏、检索、更?/em> ?em>删除 几个操作的英文首字母Q,包括 Ruby on Rails、Trails ?Grails。上面提到的q些框架Q以?AppFuseQ都让我们可以从数据库表或现有的模型对象中生成主?l节c?/p>
?1 阐述了一个典?AppFuse 应用E序的概念设计: 清单 1 l出了我们在创徏 devworks 目时所使用的命令行交互操作Q同时还l出了所生成的结果。这个项目用了 WebWork 作ؓ自己?Web 框架Q请参考下?参考资?/a> 一节给出的链接Q?/p>
在创Z个新目之后Q我们就得到了一个类g?2 所C的目录l构。Eclipse ?Intellij IDEA 目文g都是作ؓq个q程的一部分创徏的?/p>
q个目录l构?Sun ?Java 2 Platform Enterprise EditionQJ2EEQWeb
应用E序推荐的目录结构非常类伹{在 2.0 版本?AppFuse 中,q个l构会变化成适合 Apache Maven
目的标准目录结构(有关q两个目录介l的内容Q请参看 参考资?/a>
中的链接Q。AppFuse q会?Ant q移?Maven 2 上,从而获得相关下载的能力和对生成 IDE 目文g的支持。目前基?
Ant 的系l要求提交者维护项目文Ӟ?Maven 2 可以通过单地使用目?pom.xml 文g生成 IDEA、Eclipse ?
NetBeans 目文g。(q个文g位于您项目的根目录中Q是使用 Maven 构徏应用E序所需要的主要lgQ。它与利?Ant 所使用?
build.xml 文g非常cM。) 现在我们?AppFuse 是什么已l有一Ҏ念了Q在本文剩下的部分中Q我们将介绍使用 AppFuse ?7 点理由。即使您选择不?
AppFuse 来开始自q目Q也会看?AppFuse 可以为您提供很多h代码Q这些代码可以在Z Java 语言?Web
应用E序中用。由于它是基?Apache 许可证的Q因此非常欢q您在自q应用E序中重用这些代码?/p>
试是在软g开发项目中很少被给予够信ȝ一个环节。注意我q不是说在Y件开发的一些刊物中没有得到_的信任!很多文章和案例研Il出了测?
优先的开发方式和_的测试覆盖面以提高Y件的质量。然而,试通常都被看作是一件只会g镉K目开发时间的事情。实际上Q如果我们用测试优先的Ҏ在编
写代码之前就开始撰写测试用例,我相信我们可以发现这实际上会加?/em> 开发速度。另外,试优先也可以ɾl护和重?em>更加 Ҏ。如果我们不~写代码来测试自q代码Q那么就需要手工对应用E序q行试 —?q通常效率都不高。自动化才是关键?/p>
当我们首ơ开始?AppFuse Ӟ我们可能需要阅读这个项?Web 站点上提供的快速入门指南和教程Q请参看 参考资?/a>
中的链接Q。这些教E的~写是Z您可以首先编写测试用例;它们直到~写接口?或实C后才能编译。如果您有些斚w与我一P׃在开始编写代码之?
已l编写好试用例了;q是真正可以加速编写代码的惟一方式。如果您首先~写了代码的实现Q通过某种方式验证它可以工作,那么您可能会对自pQ?#8220;哦,
看v来不?—?谁需要测试呢Q我q有更多的代码需要编写!”q种情况不幸的一面是您通常都会?em>一些事?/em> 来测试自q代码Q您单地跌了可以自动化q行试的地斏V?/p>
AppFuse 的文档展CZ如何试应用E序?em>所?/em> 层次。它从数据库层开始入手,使用?DbUnitQ请参看 参考资?/a>Q在q行试之前提前使用数据来填充自q数据库。在数据讉KQDAOQ层Q它使用?Spring ? 在服务层QjMock Q请参看 参考资?/a>Q用来编写那些可以消?DAO 依赖?em>真正
?1. 典型?AppFuse 应用E序
清单 1. 使用 AppFuse 创徏新项?/strong>
alotta:~/dev/appfuse mraible$ ant new
Buildfile: build.xml
clean:
[echo] Cleaning build and distribution directories
init:
new:
[echo]
[echo] +-------------------------------------------------------------+
[echo] | -- Welcome to the AppFuse New Application Wizard! -- |
[echo] | |
[echo] | To create a new application, please answer the following |
[echo] | questions. |
[echo] +-------------------------------------------------------------+
[input] What would you like to name your application [myapp]?
devworks
[input] What would you like to name your database [mydb]?
devworks
[input] What package name would you like to use [org.appfuse]?
com.ibm
[input] What web framework would you like to use [webwork,tapestry,spring,js
f,struts]?
webwork
[echo] Creating new application named 'devworks'...
[copy] Copying 359 files to /Users/mraible/Work/devworks
[copy] Copying 181 files to /Users/mraible/Work/devworks/extras
[copy] Copying 1 file to /Users/mraible/Work/devworks
[copy] Copying 1 file to /Users/mraible/Work/devworks
install:
[echo] Copying WebWork JARs to ../../lib
[copy] Copying 6 files to /Users/mraible/Work/devworks/lib
[echo] Adding WebWork entries to ../../lib.properties
[echo] Adding WebWork classpath entries
[echo] Removing Struts-specific JARs
[delete] Deleting directory /Users/mraible/Work/devworks/lib/struts-1.2.9
[delete] Deleting directory /Users/mraible/Work/devworks/lib/strutstest-2.1.3
[echo] Deleting struts_form.xdt for XDoclet
[delete] Deleting directory /Users/mraible/Work/devworks/metadata/templates
[echo] Deleting Struts merge-files in metadata/web
[delete] Deleting 7 files from /Users/mraible/Work/devworks/metadata/web
[echo] Deleting unused Tag Libraries and Utilities
[delete] Deleting 2 files from /Users/mraible/Work/devworks/src/web/org/appfu
se/webapp
[echo] Modifying appgen for WebWork
[copy] Copying 12 files to /Users/mraible/Work/devworks/extras/appgen
[echo] Replacing source and test files
[delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/
webapp/form
[delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/
webapp/action
[copy] Copying 13 files to /Users/mraible/Work/devworks/src
[delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse
/webapp/form
[delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse
/webapp/action
[copy] Copying 5 files to /Users/mraible/Work/devworks/test
[echo] Replacing web files (images, scripts, JSPs, etc.)
[delete] Deleting 1 files from /Users/mraible/Work/devworks/web/scripts
[copy] Copying 34 files to /Users/mraible/Work/devworks/web
[delete] Deleting: /Users/mraible/Work/devworks/web/WEB-INF/validator-rules-c
ustom.xml
[echo] Modifying Eclipse .classpath file
[echo] Refactoring build.xml
[echo] ----------------------------------------------
[echo] NOTE: It's recommended you delete extras/webwork as you shouldn't ne
ed it anymore.
[echo] ----------------------------------------------
[echo] Repackaging info written to rename.log
[echo]
[echo] +-------------------------------------------------------------+
[echo] | -- Application created successfully! -- |
[echo] | |
[echo] | Now you should be able to cd to your application and run: |
[echo] | > ant setup test-all |
[echo] +-------------------------------------------------------------+
BUILD SUCCESSFUL
Total time: 15 seconds
Z么?WebWorkQ?/strong>
Struts C最q在热情地拥?WebWorkQ这U结合导致ؓ Java q_提供了一个非怼U的新 Web 框架QStruts
2。当ӞSpring MVC 是一个非怼U的基于请求的框架Q但是它不能?Struts 2 一h?JSF。基于内容的框架Q例?JSF ?
TapestryQ也都很好,但是我发?WebWork 更ؓ直观Q更Ҏ使用Q更多有? Structs 2 ?JSF 的内容请参看 参考资?/a>Q?
?2. 目的目录结?/strong>
AbstractTransactionalDataSourceSpringContextTests
c(是的Q这的确是一个类的名字!Q来允许单地加蝲 Spring 上下文文件。另外,q个cd每个 testXXX()
Ҏ装了一个事务,q当试Ҏ存在时进行回滚。这U特性得测?DAO 逻辑变得非常单,q且不会Ҏ据库中的数据造成影响?/p>
![]() |
|
?Web 层,试会验证操作(Struts/WebWorkQ、控ӞSpring MVCQ、页面(TapestryQ和理 beanQJSFQ如我们所期望的一栯行工作。Spring ?spring-mock.jar 可以非常有用地用来测试所有这些框Ӟ因ؓ它包含了一?Servlet API 的仿真实现。如果没有这个有用的库,那么试 AppFuse ? Web 框架׃变得非常困难?/p>
UI 通常是开?Web 应用E序q程中最为困隄一部分。它也是֮最l常抱怨的地方 —? q既是由于它q不是非常完,也是׃它的工作方式与我们期望的q不一栗另外,没有什么会比在客户面前作演C的q程中看到看到异常堆栈更p糕的了Q您? 应用E序可能会非常可怕,但是客户可能会要求您做到十分完美。永q不要让q种事情发生。Canoo WebTest 可以?UI q行试。它使用? HtmlUnit 来遍历测?UIQ验证所有的元素都存在,q可以填充表单的域,甚至可以验证一个假想的启用 Ajax ?UI 与我们预期的工作方式一栗(有关 WebTest ?HTMLUnit 的链接请参看 参考资?/a>。)
Zq一步简?Web 的测试,CargoQ请参看 参考资?/a>Q对 Tomcat 的启动和停止Q分别在q行 WebTest 试之前和之后)q行了自动化?/p>
![]() ![]() |
![]()
|
正如我在本文介中提到的一P很多开放源码库都已l预先集成到 AppFuse 中了。它们可以分Z下几c:
除了q些库之外,AppFuse q?Log4j 来记录日志,使用 Velocity 来构?e-mail 和菜单模ѝTomcat 可以支持最新的开发,我们可以使用 1.4 ?5 版本?Java q_来编译或构徏E序。我们应该可以将 AppFuse 部vCQ?J2EE 1.3 兼容的应用服务器上;q已l经q了试Q我们知道它在所有主要版本的 J2EE 服务器和所有主要的 servlet 容器上都可以很好地工作?/p>
?3 l出了上面创建的 devworks 目?lib 目录。这个目录中?lib.properties 文g控制了每个依赖性的版本Pq意味着我们可以单地通过把这些包的新版本攑ֈq个目录中ƈ执行诸如 ant test-all -Dspring.version=2.0
之类的命令来试q些包的新版本?/p>
?3. 目依赖?/strong>
预先集成q些开放源码库可以在项目之初极大地提高生效率。尽我们可以找到很多文档介l如何集成这些库Q但是定制工作示例ƈ单地使用它来开发应用程序要更加单?/p>
除了可以?Web 应用E序的开发之外,AppFuse 让我们还可以?Web 服务单地集成到自q目中。尽?XFire 也在 AppFuse 下蝲中一h供了Q不q如果我们希望,也可以自己集?Apache AxisQ请参看 参考资?/a> 中有?Axis 集成的教E)。另外,Spring 框架?XFire 可以一起将服务层作?Web 服务非常单地呈现出来Q这׃ؓ我们提供了开发面向服务架构的能力?/p>
另外QAppFuse q不会将我们限定CQ何特定的 API
上。它只是单地对可用的最佛_放源码解x案重新进行打包和预先集成。AppFuse 中的代码可以处理q种集成Qƈ实现?AppFuse
的基本安全性和可用性特性。只要可能,׃减少代码Q以便向 AppFuse 的依赖框架添加一个特性。例如,AppFuse 自带?Remember
Me ?SSL 切换Ҏ最q就因ؓcM的特性而从 Acegi Security 中删除了?/p>
![]() ![]() |
![]()
|
Ant 使得化了从编译到构徏再到部v的自动化q程。Ant ?AppFuse 中的一{公民,q主要是因ؓ我发现在命o行中执行操作比从 IDE 中更加简单。我们可以?Ant 实现~译、测试、部|和执行M代码生成的Q务?/p>
管q种能力对于有些人来说非帔R要,但是它ƈ不适用于所有的人。很?AppFuse 用户目前都?Eclipse ?Intellij IDEA 来构建和试自己的项目。在q些 IDE 中运?Ant 的确可以工作Q但是这样做的效率通常都不如?IDE 内置?JUnit 支持来运行测试效率高?/p>
q运的是QAppFuse 支持?IDE 中运行测试,不过理q种Ҏ对?AppFuse 开发h员来说就变得非常困难了。最大的痛苦在于 XDoclet 用来生成 Hibernate 映射文g?Web 框架所使用的一些工Ӟ例如 ActionForms ?Struts 使用? struts-config.xmlQ。IDE q不知道需要生成的代码Q除非我们配|?Ant 来编译它们,或者安装了一些可以认? XDoclet 的插件?/p>
q种对知识的~Z?AppFuse 2.0 切换?JDK 5 ?Maven 2 上的主要原因。JDK 5、注释和 Struts 2 让我们可以摆脱 XDoclet。Maven 2 用这些生成的文g和动态类路径来生?IDE 目文gQ这样对目的管理就可以q行化。目前基?Ant 的编译系l已lؓ不同的层ơ生成了一些工Ӟ包括 dao.jar、service.jar ?webapp.warQ,因此切换?Maven 的模型上应该是一个非常自然的调整?/p>
除了 Ant 之外Q它对于~译、测试、部|和报告h丰富的支持)Q对?CruiseControl 的支持也构徏C AppFuse 中。CruiseControl 是一?Continuous Integration 应用E序Q让我们可以在源代码仓库中代码发生变化时自动q行所有的试。extras/cruisecontrol 目录包含了我们ؓZ AppFuse 的项目快速、简单地讄 Continuous Integration 时所需要的文g?/p>
讄 Continuous Integration 是Y件开发周期中我们首先要做的事情之一。它不但Ȁ发程序员ȝ写测试用例,而且q通过 “You broke the build!” 游戏促进了团队之间的合作和融合?/p>
![]() ![]() |
![]()
|
AppFuse 最初是作ؓ我ؓ Apress ~写的书c?Pro JSP 中示例应用程序的一部分开发的。这个示例应用程序展CZ很多安全Ҏ和用于?Struts 开发的Ҏ。这个应用程序中的很多安全特性在 J2EE 的安全框图中都不存在。用容器管理认证(CMAQ的认证Ҏ非常单,但是 Remember Me、密码提C、SSL 切换、登记和用户理{功能却都不存在。另外,Z角色的保护方法功能在?EJB 环境中也是不可能的?/p>
最初,AppFuse 使用自己的代码和用于 CMA 的解x案完全实Cq些Ҏ。我?2004 q年初开始学?Spring 时就听说q有?Acegi Security 的知识。我?Acegi 所需要的 XML 的行敎ͼ175Q与 web.xml 中所需要的 CMA 的行敎ͼ20Q进行了比较Q很快就军_丢弃 Acegi 了,因ؓ它太q复杂了?/p>
一q半之后 —?在ؓ另外一本书 Spring Live 中编写了一章有关?Acegi Security 的内容之?—?我就改变了自qx。Acegi 的确Q目 前仍Ӟ需要很?XMLQ但是一旦我们理解了q一点,它实际上是相当简单的。当我们最l作出改变,使用 Acegi Security 的特性来全部取代 AppFuse 的特性之后,我们最l删除了大量的代码。类之上的类都已l没有了Q?#8220;Acegi handles that now” 中消q部分现在全部q入?CVS ?Attic 中了?/p>
Acegi Security ?J2EE 安全模型中曾l出现过的最好模型。它让我们可以实现很多有用的Ҏ,q些Ҏ在 Servlet API 的安全模型中都不存在Q认证、授权、角色保护方法、Remember Me、密码加密、SSL 切换、用户切换和注销。它让我们还可以用戯书存储到 XML 文g、数据库、LDAP 或单点登录系l(例如 Yale ?Central Authentication Service (CAS) 或?SiteMinderQ中?/p>
AppFuse 对很多与安全性相关的Ҏ的实现从一开始都是非怼U的。现?AppFuse 使用?Acegi SecurityQ这些特? —?以及更多Ҏ?—?都非常容易实现。Acegi 有很多地斚w可以q行扩充Q这是它使用巨大?XML 配置文g的原因。正如我们已l通过d的课E对 Acegi q行集成一P我们已经发现对很?bean 的定义进行定制可以更加紧密地? AppFuse 建立联系?/p>
Spring IoC 容器?Acegi Security 所提供的简单开发、容易测试的代码和松耦合Ҏ的l合?AppFuse
是这么好的一U开发^台的主要原因。这些框枉是不可插入的Q允许生成干净的可试代码。AppFuse
集成了很多开放源码项目,依赖注入允许对应用程序层q行单的集成?/p>
![]() ![]() |
![]()
|
有些Z代码生成称?em>代码气味的散播(code smellQ?/em>。在他们的观点中Q如果我们需要生成代码,那么很可能就会做一些错事。我們于这U确定自׃码用的模式和自动化生成代码的能力应该称?em>代码香味的I漫(code perfumeQ?/em>。如果我们正在编写类似的 DAO、管理器、操作或控gQƈ且不想ؓ它们生成代码Q那么这需要根据代码的气味来生成代码。当Ӟ当语a可以为我们提供可以简化Q务的Ҏ时Q一切都是那么美好;不过代码生成通常都是一个必需 —?通常其生产率也非帔R —?的Q务?/p>
AppFuse 中提供了一个基?Ant ?XDoclet 的代码生成工P名叫 AppGen。默认情况下Q常见的 DAO 和管理器都可以允许我们对M普通老式 Java 对象QPOJOQ进?CRUD 操作Q但是在 Web 层上q样做有些困难。AppGen 有几个特性可以用来执行以下Q务:
在运?AppGen Ӟ您会看到提示?AppGen 要从数据库表?POJO 中生成代码。如果在命o行中执行 ant install-detailed
QAppGen ׃安装 POJO 特定?DAO、管理器以及它们的测试。运?ant install
会导?Web 层的c重用通用?DAO 和默认存在的理器?/p>
Z阐述 AppGen 是如何工作的Q我们在 devworks MySQL 数据库中创徏了如清单 2 所C的表:
create table cat ( |
?extras/appgen 目录中,q行 ant install-detailed
。这个命令的输出l果对于本文来说实在太长了,不过我们在清?3 中给ZW一部分的内容:
$ ant install-detailed |
要对 cat 表用这个新生成的代码,我们需要修?
src/dao/com/ibm/dao/hibernate/applicationContext-hibernate.xmlQ来?
Hibernate d Cat.hbm.xml 映射文g。清?3 l出了我们修改后?sessionFactory
bean 的样子:
<bean id="sessionFactory" class="..."> |
在运?ant setup deploy
之后Q我们就应该可以在部|的应用E序中对 cat 表执?CRUD 操作了:
我们在上面的屏幕快照中看到的记录都是作ؓ代码生成的一部分创徏的,因此现在有试数据了?/p>
![]() ![]() |
![]()
|
我们可以扑ֈ AppFuse 各个风味的教E,q且它们都以 6 U不同的语言l出了:中文、d语、英语、韩语、葡萄牙语和西班牙语。?em>风味QflavorQ?/em> 一词,我的意思是不同框架的组合,例如 Spring MVC 加上 iBATIS、Spring MVC 加上 Hibernate ?JSF 加上 Hibernate。用这 5 U?Web 框架和两U持久框Ӟ可以有好几种l合。有兛_们的译QAppFuse q默认Ҏ提供了 8 U翻译。可用语a包括中文、荷兰语、d语、英语、法语、意大利语、葡萄牙语和西班牙语?/p>
除了核心教程之外Q还d了很多教E(请参?参考资?/a>Q?来介l与各种数据库、应用服务器和其他开放源码技术(包括 JasperReports、Lucene、Eclipse、Drools、Axis ?DWRQ的集成?/p>
![]() ![]() |
![]()
|
Apache 软g基金会对于开放源码有一个有的看法。它对围l开放源码项目开发一个开放源码社区最感兴。它的成员相信如果社区非常强大,那么产生高质量的代码是一个自然的q程。下面的内容引自 Apache 主页Q?/p>
“我们认ؓ自己不仅仅是一l共享服务器的项目,而且是一个开发h员和用户的社区?#8221;
AppFuse C?2003 q作?SourceForge 上的一个项目(?struts.sf.net
的一部分Q启动以来,已经获得了极大的增长。通过?2004 q?3 月{换到 java.net 上之后,它已l成里一个非常流行的目Q从
2005 q?1 月到 3 月成问量最多的一个项目。目前它仍然是一个非常流行的目Q有?java.net 目l计信息的链接,请参?参考资?/a>Q,不过在这个站点上它正在让位于 Sun 赞助的很多项目?/p>
?2004 q年末,Nathan Anderson 成ؓl我之后W一个提交者。此后有很多人都加入了进来,包括 Ben
Gill、David Carter、Mika G?ckel、Sanjiv Jivan ?Thomas
Gaudin。很多现有的提交者都已经通过各种方式作出了自q贡献Q他们都帮助 AppFuse C成ؓ一个迅速变化ƈ且非常有的地方?/p>
邮g列表非常友好Q我们试囄护这样一条承?“没有问题是没有h理会的问?#8221;。我们的邮g列表归档文g中惟一一?“RTFM”
是从用户那里发出的,而不是从开发者那里发出的。我们绝对信?Apache 开放源码社区的哲学。引用我最好的朋友 Bruce Snyder
的一句话Q?#8220;我们Z码而来QؓZ而留?#8221;。目前,大部分开发者都是用P我们通常都喜Ƣ有一D늾妙的旉。另外,大部分文档都是由C~写的;因此Q?
q个C的知识是非常渊博的?/p>
![]() ![]() |
![]()
|
我们应该试使用 AppFuse q行开发,q是因ؓ它允许我们简单地q行试、集成、自动化Qƈ可以安全地生?Web 应用E序。其文档非常丰富Q社Z非常友好。随着其支撑框架越来越好,AppFuse 也将不断改进?/p>
?AppFuse 2.0 开始,我们计划q移?JDK 5Q仍然支持部|到 1.4Q和 Maven 2 上去。这些工具可以简化? AppFuse 的开发、安装和升。我们计划充分利?Maven 2 的功能来处理相关依赖性。我们将到诸如 appfuse-hibernate-2.0.jar ?appfuse-jsf-2.0.jar 之类的工件。这些工仉可以?pom.xml 文g中进行引用,它们负责提取其他相关依赖性。除了在自己的项目中使用 AppFuse 基类之外Q我们还可以像普通的框架一样在 JAR 中对q些cȝ单地q行扩展Q这应该会大大简化它的升U过E,q励更多用户将自己希望的改q提交到q个目中?/p>
如果没有其他问题Q?AppFuse 可以让您始终处于 Java Web 开发的技术前沿上 —?像我们一P
转自:http://blog.chinaunix.net/u/11409/showart_436247.html
http://blog.csdn.net/changzhang/category/369570.aspx可参考这个网址
AppFuse是一个集成了当前最行的Web应用框架的一个更高层ơ的Web开发框Ӟ也可以说是一个Web开发基q_Q它与它所集成的各U框架相比,它提供了一部分所有Webpȝ开发过E中都需要开发的一些功能,如登陆、用户密码加密,用户理、根据不同的用户可以展现不同的菜单,可以自动生成 40%-60%左右的代码,自带了默认的一些在CSS中设定的样式Q用这些样式能很快的改变整个系l的外观Q还有自动化试的功能?/p>
它最大的价值就是ؓ我们提供了一个Web开发的新的方式和思\Q尽这些技术在国外都已q很行了,但在国内能够Hibernate、Struts?Spring、DBUnit、Ant、Log4J、Struts Menu、Xdoclet、SiteMesh、Velocity、JUnit、JSTL、WebWorkq些技术集成到一个框架中的还不多见,所以即使不使用它的全部功能Q它也给我们提供了一个很好的借鉴、学习的Z?/p>
通过xAppFuseQ我们可以看到目前国外的L开发都使用了哪些技术,开发方式是什么样的,可能辑ֈ什么样的结果,而在以前Q是很少能够看到q样完整的例子的?/p>
AppFuse的另一个启C是Q我们可以依靠开源Y件的功能降低开发成本,而且可以阅读开源Y件的代码提高所在团队的整体实力?/p>
AppFuse 的作?Matt Raible是当今开源世界一个比较活跃的开发者,它是AppFuse、Struts Menu的作者,也是XDoclet、DisplayTag{一些著名开源项目的U极参与者,《Hibernate In Action》的作者就在感谢的名单里面提到他,XDoclet的下载版本中所带的Hibernate标签部分的例子就是他写的Q他q是2004q?Apache技术年会的主讲Z一?/p>
但是通过2个月的实际学习和使用Q我也遇Cpd的问题,因ؓAppFuse是将其他的一些类库或者框枉成在一LQ集成的技术众多,而且有一些技术在国内甚至很少有h知道Q资料也比较,所以虽然作者经q了一些测试,但都是基于英文编码的Q而对于中文编码来_q潜在的存在着一些问题,虽然不是AppFuse的问题,但却降低了开发速度Q下面是我在开发过E中遇到q的问题Q有些解决了Q有些还没有解决Q?br />
一QStruts
1Q?AppFuse中默认的MVC框架是StrutsQ而且使用的是LookupDispatchActionQƈ且用的是按钮(buttonQ,在XP下用IE览效果q可以,但如果在2000或?8下,׃外观很难看,而且当时我还遇到一个问题:如果按钮昄中文Q则在DisplayTag中翻失灵,而且报错Q后来我把BaseAction的相x法改变了Q才可以使用Q因为国内的客户都比较重视界面,所以后来我那些按钮都Ҏ囄了,当然也要d一些方法了Q有炚w烦!
2Q?Struts中的标签如今推荐使用的只有html部分的标{了Q其他的标签或者可以用JSTL替代Q或者已l不推荐使用了,而且AppFuse中推荐用JSTLQ而JSTL和struts的标{联合使用Ӟ需要的不是<html:标签>Q而是<html-el:标签>Q这个问题曾l困C我整?天?br />
3Q?Struts的Validation的校验规则ƈ不完善,比如如果使用客户端的javascript校验Q则在邮׃输入汉字Ҏ校验不出来,C服务器端报错?br />
4Q最严重的问题是AppFuse生成的Struts的validation.xml文g中有许多多余?#8220;.”Q如果你L了,常常在执行ant?deployd时又恢复原样。这h提交表单的时候经怼报javascript的脚本错误或者缺对象或者缺valueQ所以我会手工的修改q个文gQ然后把修改后的文g备䆾Q当重新生成有错误的文gӞ我会用备份的没有错误的文件去覆盖?br />
5Q?Struts的validatioin对于使用同一个FormBean的Action的校验方式比较复杂。(待解冻I?br />
二.Hibernate
1Q?Hibernate是现在受到越来越多的人推崇的一个ORM工具Q框架、类库)Q它我们从J琐的用JDBC的开发过E中解放出来Q但同时也带来了新的问题Q如学习曲线Q执行效率,数据库设计优化,q有最重要的灵zL。Hibernate不是一个很Ҏ上手的东西,要完全驾驭它q需要读很多资料Q但好的资料却很?br />
2Q?使用Xdoclet可以很方便的生成Hibernate中的持久cȝ配置文gQ?.hbm.xmlQ?但对一些特D的映射却无能ؓ力,如用序列的id生成规则Q序列的名字没有地方写,所以也只好先利用它生成主要的内容,然后手工修改?br />
3Q?同样q是id的生成策略问题,如果使用序列、hilo{需要一些数据库机制支持的策略时QschemaExportq不能自动生成序列或者保存当前id的表Q这工作仍然要手工解决?br />
4Q?Hibernate中提供了几种兌Q一对一、一对多、多对多Q但对于怎样调整效率却没有一个很明确的提C,q要Ҏ情况判定Q这带来和一些弹性的设计?br />
5Q?Hibernate中可以选择的操作数据库的方式有3U,其中HQL功能最强大Q但有些功能使用标准查询可能会更方便Q但会有一些限Ӟ所以虽然它很灵z,但易用性不如JDBC好?br />
三.Spring
在AppFuse的过E中QSpring完全隐藏在幕后,除了一些配|外Q几乎感觉不到它的存在,所以我在用它的过E中q没有遇C么麻烦,q里只是单的介绍一下它在AppFuse中v到的作用?br />
1Q?Spring在AppFuse中v到的主要作用是对Hibernate的Session和事务的理Q利用Spring装的Hibernate模板c,我们大大地减了实现DAO的代码行数?br />
2Q?SpringqvCq接映射文g和类之间的关联,及接口和实现cM间的兌Q这些都依赖于Spring的IoC的机制的实现?br />
3Q?对于字符q行~码和解码部分用CSpring自带的FilterQ只需要在配置文g中配|就好了?/p>
四.SiteMesh
SiteMesh是一个基于Decorator模式的技术,它可以修饰返回的|页文gQ它的工作方式受到越来越多的人的推崇Q这点从Manning出版的一些技术书c中可以看出来?br />
我在使用SiteMesh的过E中q不利Q我参考了《Java Open Source Programming》,q本书中说SiteMesh在默认的情况下不对下载文件进行装饎ͼ但我在下载文件时发现Q我的文件内容被丢弃了,取而代之的?SiteMesh的模板的内容Q后来我通过修改SiteMesh的配|文件解决了q个问题Q但感觉q有一些不太清楚的地方需要学习?/p>
五.DisplayTag
DisplayTag 是一个优U的显C内容的标签Q从SourceForge的访问量来看Q它是很z跃的项目,仅次于Ant、Hibernate、Xdoclet{几个著名的目Q我ȝQ它的主要功能有4:昄、分c排序、将昄的数据写入指定类型的文g中,然后下蝲?br />
1Q?据我使用的情늜Q我只用了分页和显C的功能Q因为当时我没有很好的解决中文编码的问题Q所以排序会有问题,直到昨天Q我在朋友的帮助下解决了q个问题Q至此我可以攑ֿ使用的功能又增加了排?我昨天简单的试了一下是可以??/p>
2Q?但对于将昄的内容生成到一个指定格式的文g中的功能却有着很多~陷Q如Q?br /> Q?Q?生成的文件中只有昄的数据,那些没有昄在界面上的的数据Q则不会被写到文件中?br /> Q?Q?如果修改了DisplayTag的显C的内容Q比如添加一列,在这列中的内容不是字W,而是HTML的标{,则生成的文g只有q些HTML标签Q而没有数据?br /> Q?Q?即DisplayTag中没有我们定制的HTML脚本Q生成的文g偶尔也有问题Q比如:它会?#8220;007”生成?#8220;7”Q把字符串自动的转换为整型倹{有时候还生成I白内容的文件?br /> Q?Q?DisplayTag生成的Excel文g兼容性不好,有时在Excel2003中不能正常打开Q或者在XP下打开报错?br /> 后来Q我看了作者写的《Spring Live》,书中说如果想实现E_的ExcelQ推荐用POIQ于是我使用POI生成ExcelQ稳定性和兼容性都不错?/p>
六.DBUnit
DBUnit是一个可以被Ant集成的向数据库中d数据和备份数据的一个类库,配置很方便,因ؓAppFuse已经集成好了Q所以用也很容易?br />
但是如果你用EditPlus之类的工h工修改了AppFuse生成的内容,则执行Ant的setup、setup-db或者deploy的Q务时Q常常报错,说无效的格式Q这是因个被手工修改的文件再ơ被AppFuse执行后,它的W一行的文g声明的前几个字母是无效的Q是因ؓ本地的字W集~码的原因而引起了qQ如果把q几个无效的字母LQ问题就解决了?/p>
七.Struts Menu
Struts Menu也是AppFuse的作者开发的一个开源YӞ它可以根据配|文件读取当前用户可以用的功能菜单Q这个功能是我一直以来都惌的,我也扑ֈ了一些代码,但实现的都不如这个完善,没什么好说的Q用简单,配置ҎQ很好的解决了我的问题?br />
问题是我只用了AppFuse提供?个角Ԍ对于多个角色的实验我q没有做?/p>
八.XDoclet
在AppFuse中,使用Xdoclet生成了几乎一切的配置文gQStruts-config.xml、web.xml、validation.xml?.hbm.xml{文Ӟ如果使用AppGen的话Q还会生成更多的文gQ这一切都是用Xdoclet实现的?br />
问题是我在Struts部分提到的,生成的Validation.xml文g中会多生成一?#8220;.”Q另外在生成资源文g时也会多生成一?#8220;.”Q目前我没有很好的阅读这D代码,不知道是不是Xdoclet的问题?/p>
九.Ant
Antq没有什么问题,但在执行作者写的Antd的时候,有一些Q务不能正常执行,比如Q运行模拟对象测试的dQ作者也?.7版本的修复列表中提到以前版本有些antd不能执行Q在1.7中修改了一些antdQ他们能够正常的执行了?br />
实际上,我们如果使用AppGenq行开发的话,使用的Q务一般不过8个?/p>
十.JSTL
JSTL 是个好东西,我常用的?lt;c:>?lt;fmt:>部分的标{,但是如果使用JSTLq行逻辑判断Q我q没有感觉比使用JSP的代码块优雅多少。另外,熟悉JSTL也需要一D|_我就l历了面对着JSP面不知道该怎么写JSTL语法的困境。当ӞAppFuse中用的基本都是 JSTLQ包括向DisplayTag传递显C的数据Q用的都是JSTL语法Q这斚w的资料挺多,我参考的是电子工业出版社出的《JSP2.0技术》,说的很详l?/p>
十一.Tomcat
你也怼_“Tomcat׃用说了吧Q?#8221;Q是的,Tomcat一般都会用,但是 ―――――――――――――Tomcat5和Tomcat4.X对于中文~码使用了不同的机制Q这个问题困C我好久,我解决了面上写入汉字显CZؕ码的问题Q我也曾l以为DisplayTagҎ字不能排序,也不能正常分|因ؓDisplayTag的开发者都是老外Q是因ؓ他们没有考虑中文的关pȝ原因?br />
直到昨天Q我才知道这一切都是因为Tomcat5Ҏ字编码的实现的方式和Tomcat4不一L原因Q如果感兴趣Q可以看看这个帖子: http://www.javaworld.com.tw/jute/post/view?bid=9&id=44042&sty=1&tpg=1&age=0
十二.JavaScript
JavaScript单易学,但想q用自如׃太容易了。AppFuse中嵌入了几个js文gQ里面包含了许多函数Q值得我们好好的研I一下,比如Q如果有一个必填字D|有填写,AppFuse会自动的聚焦在那个input上,cM的小技巧有很多Q你可以自己ȝ看?br />
但AppFuse 自带的JavaScript脚本有一个BugQ就是当DisplatyTag中没有可以显C的数据Ӟ你用鼠标单击Q它会报JavaScript错误Q你仔细研究一下function highlightTableRows(tableId) q道了Q我的解军_法是在location.href = link.getAttribute("href");前面d一行判断:if (link != null)?/p>
十三.资源文g国际?br /> 对于Struts和DisplayTag都涉及到资源文g国际化AppFuse1.6.1很好的解决了Struts资源映射文g国际化的问题Q你只需要在对应本国语言的资源文件中写入汉字QAnt中有一Ҏ行native2ascii的Q务,AppFuse自动的ؓ你进行了资源文g的编码{换,而对?DisplayTag的资源文仉题,q要自己执行native2ascii命oQؓ了避免每ơ都输入一串命令,我用Delphi写了个小工具Q可视化的选择资源文gQ点L钮自动执行该命oQ底层依赖于JDK?/p>
l过2个多月的学习Q我感觉q个框架非常不错Q它为我以后的项目开发指Z一个新的方向,但如果想很熟l的使用q个框架q行开发,臛_要对以下几种技术比较熟l:Struts(或者WebWork、Spring及其他的已经整合q来的MVC框架)、HibernateQ或者ibatisQ、JSTLQ当然其他的技术至也要知道一点,否则遇到问题都不知道出在哪里?/p>
目前我还没有解决的问题有Q?br />
1Q?如何在翻늚时候才d下面的数据?
2Q?怎样对用同一个FormBean的多个Formq行客户端校验?
3Q?怎样优化Hibernate的效率?《Hibernate In Action》中提供了多U策略,有些时候应该用lazyQ有些时候应该用outer-join?br />
4Q在什么时机生成导出文Ӟ目前我是在查询的Action中同时生成了导出文gQ否则,C下一,我就不知道查询条件了Q当Ӟ如果把拼装后的HQL存储在Session或者Hidden中也可以解决q个问题Q但是这样就破坏了DAO的封装,要把DAO装后的HQL发送给ActionQ然后发送的?Web界面层,所以目前我q在犹U生成导出文g的时机选择在哪里?
5Q?什么时候应该自p取数据库q接Q执行native SQLQ具体需要注意些什么?
6Q?SiteMesh的模板优化?
7Q?DisplayTag的底层实玎ͼ
每个问题都比较棘手,要一个一个解冻I
q个框架的优ҎQ如果熟悉了开发流E,可以大幅度的提高开发速度Q如果业务不是很复杂Q用AppGen可以生成60%左右的代码,而且E序可维护性好Q因Z者用了多个设计模式对各个层面进行了装Q所以不同的模块代码风格出奇的一_有利于开发h员快速上手,也有利于接收其他开发h员遗留的代码?/p>
兔八?br /> 2004-2-3下午15:51
++++++++++++++++++++
引用:
有没有成功的目同我们分享一?
我已l用AppFuse开发了2个项目了Q都是教育系l的Q系l都不大Q我一个h用实际开发一个月Q因为是公司的项目,源码不好外发Q但主要的东襉K是一LQ对于AppFuse我也没有修改多少Q否则,往新版本移植就会有问题了?br /> 我遇到的问题Q能惌v来的我都写下来了Q如果有其他的问题,我们可以一赯论?br /> 最q我有个朋友在用WebWork的AppFuse版本q行开发,他遇到的问题和我基本差不多,有交才有进步,呵呵Q?br /> Very Happy
感谢g几位的热心解{,谢谢Q?/p>
+++++++++++++++++++++++
引用:
目前我还没有解决的问题有Q?br />
1Q?如何在翻늚时候才d下面的数据?
2Q?怎样对用同一个FormBean的多个Formq行客户端校验?
3Q?怎样优化Hibernate的效率?《Hibernate In Action》中提供了多U策略,有些时候应该用lazyQ有些时候应该用outer-join?br />
4Q在什么时机生成导出文Ӟ目前我是在查询的Action中同时生成了导出文gQ否则,C下一,我就不知道查询条件了Q当Ӟ如果把拼装后的HQL存储在Session或者Hidden中也可以解决q个问题Q但是这样就破坏了DAO的封装,要把DAO装后的HQL发送给ActionQ然后发送的?Web界面层,所以目前我q在犹U生成导出文g的时机选择在哪里?
5Q?什么时候应该自p取数据库q接Q执行native SQLQ具体需要注意些什么?
6Q?SiteMesh的模板优化?
7Q?DisplayTag的底层实玎ͼ
1.关于页的问题,如果你刚开始用AppFuse开发的话,推荐使用valuelist,它可以和Hibernate很好的集成,我的一个网友用的就是这个东西,虽然界面没有DisplayTag漂亮Q但关于分页却不用你操太多的心,
因ؓq几天天天开会,所以也没有做些技术实验,另一个朋友告诉我有一个老外把DisplayTag分页部分修改了,在JIRA上有源码下蝲Q我下来了,q没有看Q还有一个思\Q就是分析DisplayTag的分늚格式Q然后用Filter解析Q然后把当前号传入DAOQ然后用标准查询进行查询分,但要对AppFuse的接口和Ҏd参数Q正在犹豫中Q还有更单的ҎQ直接在Session中放入当前的号Q每ơ都hQ就不用Filter了,然后同样修改Ҏ和接口?/p>
2.对于Struts的用同一个FormBean的多个Formq行客户端校验,在孙卫琴的Struts的书中已l提CQ即使她的方法不用Q也可以手写JavaScript来解冻I只是我不愿意而已Q如果别无他法,则只能如此了?/p>
3. 优化Hibernate的效率,其实Ҏ的程序来说问题不大,我的表比较少Q基本只?层的U联Q而且对于数据字典和业务表之间的关联,我采用的是业务表到数据字典表的many-to-oneQ这L单向兌比较单,也能够满x的要求,性能会好一点点Q再加上分页功能Q只查询当前也内容,然后参考《Hibernate In Action》的W七章的内容Q提高接收效率应该是没有问题的?/p>
4.关于到处文g的时机,我正在看关于模式的书c,正在扄案,其实q有个简单的办法Q就是把生成导出文g单独的实玎ͼ用户点击按钮才生产,当然q样p把用L查询条gC来,当然也涉及到修改接口和方法了QAppFuse中,修改接口和方法很ȝQ如果代码生成后再修改,要改动很多处Q所以前期设计很重要?/p>
5.关于q一点,我一直在找一个硬性的标准Q比如关联表过多少个等{条件就应该自己获取数据库连接,但现在看来这也不是绝对的Q如果能够大q度提高效率Q或者?native SQL可以减少工作量或者节省时间的话,那就可以使用Q只是要对这U方式的利弊要有所了解Q不q的是,我还没有q样试过Q试q的朋友h供些Q谢谢!
6.SiteMesh的优化,我看C片文章,也是个老外写的Q忘了出处,说SiteMeshҎ能影响不大Q可以放心用,那我暂时不考虑它了Q呵c?/p>
7.DisplayTag的底层的原理我早q道,而且它的文档的流E图也有Q只是我需要知道更详细的实现细节,最q在L码,应该很快有l果了,如果我有好消息,会来q里把解x案脓出来?/p>
上面的文字只是我目前的一些思\Q因为天天开会,也没有做技术实验,q不知道可行的程度,但我惛_该都可以实现Q我只不q是在找更好的办法,如果你有M好的思\或者徏议,请不吝告知,谢谢QQ何徏议和意见都是受欢q的Q只是要详细些,不要拿些I洞的模式来敯我,呵呵Q目前这L“高手”不少Q我有些受够了,呵呵
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/changzhang/archive/2008/03/12/2172675.aspx