﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-小菜毛毛技术分享-随笔分类-appfuse 集成J2EE框架</title><link>http://www.blogjava.net/caizh2009/category/45833.html</link><description>与大家共同成长</description><language>zh-cn</language><lastBuildDate>Mon, 02 Aug 2010 09:38:22 GMT</lastBuildDate><pubDate>Mon, 02 Aug 2010 09:38:22 GMT</pubDate><ttl>60</ttl><item><title>使用 AppFuse 的七个理由</title><link>http://www.blogjava.net/caizh2009/archive/2010/08/02/327771.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Mon, 02 Aug 2010 09:38:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/08/02/327771.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/327771.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/08/02/327771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/327771.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/327771.html</trackback:ping><description><![CDATA[<blockquote>开始学习在 Java&#8482; 平台上使用诸如 Spring、Hibernate 或 MySQL
之类的开放源码工具时可能非常困难。再加上 Ant 或 Maven，以及与 DWR 一起的小 Ajax，还有 Web 框架 —— 即
JSF，我们必须睁大眼睛盯着如何配置应用程序。AppFuse
减少了集成开放源码项目的痛苦。它可以把测试变成一等公民，让我们可以从数据库表生成整个 UI，并使用 XFire 来支持 Web
服务。另外，AppFuse 的社区也非常健全，这是不同 Web 框架用户可以一起融洽相处的地方之一。</blockquote>
<p>AppFuse
是一个开放源码的项目和应用程序，它使用了在 Java 平台上构建的开放源码工具来帮助我们快速而高效地开发 Web
应用程序。我最初开发它是为了减少在为客户构建新 Web 应用程序时所花费的那些不必要的时间。从核心上来说，AppFuse
是一个项目骨架，类似于通过向导创建新 Web 项目时 IDE 所创建的东西。当我们使用 AppFuse
创建一个项目时，它会提示我们将使用开放源码框架，然后才创建项目。它使用 Ant
来驱动测试、代码生成、编译和部署。它提供了目录和包结构，以及开发基于 Java 语言的 Web 应用程序所需要的库。</p>
<p>与大部分 &#8220;new project&#8221; 向导不同，AppFuse
创建的项目从最开始就包含很多类和文件。这些文件用来实现特性，不过它们同时也会在您开发应用程序时被用作示例。通过使用 AppFuse
启动新项目，我们通常可以减少一到两周的开发时间。我们不用担心如何将开放源码框架配置在一起，因为这都已经完成了。我们的项目都已提前配置来与数据库进
行交互，它会部署到应用服务器上，并对用户进行认证。我们不必实现安全特性，因为这都早已集成了。</p>
<p>当我最初开发 AppFuse 时，它只支持 Struts 和 Hibernate。经过几年的努力，我发现了比 Struts 更好的 Web
框架，因此我还添加了为这些 Web 框架使用的选项。现在，AppFuse 可以支持 Hibernate 或 iBATIS 作为持久性框架。对于
Web 框架来说，我们可以使用 JavaServer Faces（JSF）、Spring MVC、Struts、Tapestry 或
WebWork。</p>
<p>AppFuse 提供了很多应用程序需要的一些特性，包括：</p>
<ul>
    <li>认证和授权</li>
    <li>用户管理</li>
    <li>Remember Me（这会保存您的登录信息，这样就不用每次都再进行登录了）</li>
    <li>密码提醒</li>
    <li>登记和注册</li>
    <li>SSL 转换</li>
    <li>E-mail</li>
    <li>URL 重写</li>
    <li>皮肤</li>
    <li>页面修饰</li>
    <li>模板化布局</li>
    <li>文件上载</li>
</ul>
<p>这种 &#8220;开箱即用&#8221; 的功能是 AppFuse 与其他 <em>CRUD 代</em> 框架的区别之一（CRUD 取自<em>创建、检索、更新</em> 和<em>删除</em> 几个操作的英文首字母），包括 Ruby on Rails、Trails 和 Grails。上面提到的这些框架，以及 AppFuse，都让我们可以从数据库表或现有的模型对象中生成主页/细节页。</p>
<p>图 1 阐述了一个典型 AppFuse 应用程序的概念设计：</p>
<br />
<a name="fig1"><strong>图 1. 典型的 AppFuse 应用程序</strong></a><br />
<img alt="典型的 AppFuse 应用程序" src="http://www.ibm.com/developerworks/cn/java/j-appfuse/appfuse_application.gif" height="547" width="572" />
<br />
<p>清单 1 给出了我们在创建 <em>devworks</em> 项目时所使用的命令行交互操作，同时还给出了所生成的结果。这个项目使用了 WebWork 作为自己的 Web 框架（请参考下面 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a> 一节给出的链接）。</p>
<br />
<a name="listing1"><strong>清单 1. 使用 AppFuse 创建新项目</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre>alotta:~/dev/appfuse mraible$ ant new<br />
            Buildfile: build.xml<br />
            <br />
            clean:<br />
            [echo] Cleaning build and distribution directories<br />
            <br />
            init:<br />
            <br />
            new:<br />
            [echo] <br />
            [echo] +-------------------------------------------------------------+<br />
            [echo] |    -- Welcome to the AppFuse New Application Wizard! --     |<br />
            [echo] |                                                             |<br />
            [echo] | To create a new application, please answer the following    |<br />
            [echo] | questions.                                                  |<br />
            [echo] +-------------------------------------------------------------+<br />
            <br />
            [input] What would you like to name your application [myapp]?<br />
            devworks<br />
            [input] What would you like to name your database [mydb]?<br />
            devworks<br />
            [input] What package name would you like to use [org.appfuse]?<br />
            com.ibm<br />
            [input] What web framework would you like to use [webwork,tapestry,spring,js<br />
            f,struts]?<br />
            webwork<br />
            [echo] Creating new application named 'devworks'...<br />
            [copy] Copying 359 files to /Users/mraible/Work/devworks<br />
            [copy] Copying 181 files to /Users/mraible/Work/devworks/extras<br />
            [copy] Copying 1 file to /Users/mraible/Work/devworks<br />
            [copy] Copying 1 file to /Users/mraible/Work/devworks<br />
            <br />
            install:<br />
            [echo] Copying WebWork JARs to ../../lib<br />
            [copy] Copying 6 files to /Users/mraible/Work/devworks/lib<br />
            [echo] Adding WebWork entries to ../../lib.properties<br />
            [echo] Adding WebWork classpath entries<br />
            [echo] Removing Struts-specific JARs<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/lib/struts-1.2.9<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/lib/strutstest-2.1.3<br />
            [echo] Deleting struts_form.xdt for XDoclet<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/metadata/templates<br />
            [echo] Deleting Struts merge-files in metadata/web<br />
            [delete] Deleting 7 files from /Users/mraible/Work/devworks/metadata/web<br />
            [echo] Deleting unused Tag Libraries and Utilities<br />
            [delete] Deleting 2 files from /Users/mraible/Work/devworks/src/web/org/appfu<br />
            se/webapp<br />
            [echo] Modifying appgen for WebWork<br />
            [copy] Copying 12 files to /Users/mraible/Work/devworks/extras/appgen<br />
            [echo] Replacing source and test files<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/<br />
            webapp/form<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/<br />
            webapp/action<br />
            [copy] Copying 13 files to /Users/mraible/Work/devworks/src<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse<br />
            /webapp/form<br />
            [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse<br />
            /webapp/action<br />
            [copy] Copying 5 files to /Users/mraible/Work/devworks/test<br />
            [echo] Replacing web files (images, scripts, JSPs, etc.)<br />
            [delete] Deleting 1 files from /Users/mraible/Work/devworks/web/scripts<br />
            [copy] Copying 34 files to /Users/mraible/Work/devworks/web<br />
            [delete] Deleting: /Users/mraible/Work/devworks/web/WEB-INF/validator-rules-c<br />
            ustom.xml<br />
            [echo] Modifying Eclipse .classpath file<br />
            [echo] Refactoring build.xml<br />
            [echo] ----------------------------------------------<br />
            [echo] NOTE: It's recommended you delete extras/webwork as you shouldn't ne<br />
            ed it anymore.<br />
            [echo] ----------------------------------------------<br />
            [echo] Repackaging info written to rename.log<br />
            [echo] <br />
            [echo] +-------------------------------------------------------------+<br />
            [echo] |           -- Application created successfully! --           |<br />
            [echo] |                                                             |<br />
            [echo] | Now you should be able to cd to your application and run:   |<br />
            [echo] | &gt; ant setup test-all                                        |<br />
            [echo] +-------------------------------------------------------------+<br />
            <br />
            BUILD SUCCESSFUL<br />
            Total time: 15 seconds</pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
    <tbody>
        <tr>
            <td width="10"><img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /></td>
            <td>
            <table border="1" cellpadding="5" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td bgcolor="#eeeeee">
                        <a name="sidebar1"><strong>为什么使用 WebWork？</strong></a><br />
                        Struts 社区最近在热情地拥抱 WebWork，这种结合导致为 Java 平台提供了一个非常优秀的新 Web 框架：Struts
                        2。当然，Spring MVC 是一个非常优秀的基于请求的框架，但是它不能像 Struts 2 一样支持 JSF。基于内容的框架（例如 JSF 和
                        Tapestry）也都很好，但是我发现 WebWork 更为直观，更容易使用（更多有关  Structs 2 和 JSF 的内容请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>）。
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<p>在创建一个新项目之后，我们就得到了一个类似于图 2 所示的目录结构。Eclipse 和 Intellij IDEA 项目文件都是作为这个过程的一部分创建的。</p>
<br />
<a name="fig2"><strong>图 2. 项目的目录结构</strong></a><br />
<img alt="项目的目录结构" src="http://www.ibm.com/developerworks/cn/java/j-appfuse/project_directory_structure.jpg" height="366" width="173" />
<br />
<p>这个目录结构与 Sun 为 Java 2 Platform Enterprise Edition（J2EE）Web
应用程序推荐的目录结构非常类似。在 2.0 版本的 AppFuse 中，这个结构会变化成适合 Apache Maven
项目的标准目录结构（有关这两个目录介绍的内容，请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>
中的链接）。AppFuse 还会从 Ant 迁移到 Maven 2 上，从而获得相关下载的能力和对生成 IDE 项目文件的支持。目前基于
Ant 的系统要求提交者维护项目文件，而 Maven 2 可以通过简单地使用项目的 pom.xml 文件生成 IDEA、Eclipse 和
NetBeans 项目文件。（这个文件位于您项目的根目录中，是使用 Maven 构建应用程序所需要的主要组件）。它与利用 Ant 所使用的
build.xml 文件非常类似。）</p>
<p>现在我们对 AppFuse 是什么已经有一点概念了，在本文剩下的部分中，我们将介绍使用 AppFuse 的 7 点理由。即使您选择不使用
AppFuse 来开始自己的项目，也会看到 AppFuse 可以为您提供很多样板代码，这些代码可以在基于 Java 语言的 Web
应用程序中使用。由于它是基于 Apache 许可证的，因此非常欢迎您在自己的应用程序中重用这些代码。</p>
<p><a name="1">理由 1：测试</a></p>
<p>测试是在软件开发项目中很少被给予足够信任的一个环节。注意我并不是说在软件开发的一些刊物中没有得到足够的信任！很多文章和案例研究都给出了测试
优先的开发方式和足够的测试覆盖面以提高软件的质量。然而，测试通常都被看作是一件只会延长项目开发时间的事情。实际上，如果我们使用测试优先的方法在编
写代码之前就开始撰写测试用例，我相信我们可以发现这实际上会<em>加速</em> 开发速度。另外，测试优先也可以使维护和重用<em>更加</em> 容易。如果我们不编写代码来测试自己的代码，那么就需要手工对应用程序进行测试 —— 这通常效率都不高。自动化才是关键。</p>
<p>当我们首次开始使用 AppFuse 时，我们可能需要阅读这个项目 Web 站点上提供的快速入门指南和教程（请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>
中的链接）。这些教程的编写就是为了您可以首先编写测试用例；它们直到编写接口和/或实现之后才能编译。如果您有些方面与我一样，就会在开始编写代码之前
就已经编写好测试用例了；这是真正可以加速编写代码的惟一方式。如果您首先编写了代码的实现，通过某种方式验证它可以工作，那么您可能会对自己说，&#8220;哦，
看起来不错 —— 谁需要测试呢？我还有更多的代码需要编写！&#8221;这种情况不幸的一面是您通常都会做<em>一些事情</em> 来测试自己的代码；您简单地跳过了可以自动化进行测试的地方。</p>
<p>AppFuse 的文档展示了如何测试应用程序的<em>所有</em> 层次。它从数据库层开始入手，使用了 DbUnit（请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>）在运行测试之前提前使用数据来填充自己的数据库。在数据访问（DAO）层，它使用了 Spring 的 <code>AbstractTransactionalDataSourceSpringContextTests</code> 类（是的，这的确是一个类的名字！）来允许简单地加载 Spring 上下文文件。另外，这个类对每个 <code>testXXX()</code> 方法封装了一个事务，并当测试方法存在时进行回滚。这种特性使得测试 DAO 逻辑变得非常简单，并且不会对数据库中的数据造成影响。</p>
<p>在服务层，jMock （请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>）用来编写那些可以消除 DAO 依赖的<em>真正</em> 单元测试。这允许进行验证业务逻辑正确的快速测试；我们不用担心底层的持久性逻辑。</p>
<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
    <tbody>
        <tr>
            <td width="10"><img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" /></td>
            <td>
            <table border="1" cellpadding="5" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td bgcolor="#eeeeee">
                        <a name="sidebar2"><strong>HtmlUnit 支持</strong></a><br />
                        HtmlUnit 团队在 1.8 发行版中已经完成了相当多的工作来确保包可以与流行的 Ajax 框架（Prototype 和 Scriptaculous）很好地工作。
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<p>在 Web 层，测试会验证操作（Struts/WebWork）、控件（Spring MVC）、页面（Tapestry）和管理
bean（JSF）如我们所期望的一样进行工作。Spring 的 spring-mock.jar
可以非常有用地用来测试所有这些框架，因为它包含了一个 Servlet API 的仿真实现。如果没有这个有用的库，那么测试 AppFuse 的
Web 框架就会变得非常困难。</p>
<p>UI 通常是开发 Web 应用程序过程中最为困难的一部分。它也是顾客最经常抱怨的地方 ——
这既是由于它并不是非常完美，也是由于它的工作方式与我们期望的并不一样。另外，没有什么会比在客户面前作演示的过程中看到看到异常堆栈更糟糕的了！您的
应用程序可能会非常可怕，但是客户可能会要求您做到十分完美。永远不要让这种事情发生。Canoo WebTest 可以对 UI 进行测试。它使用了
HtmlUnit 来遍历测试 UI，验证所有的元素都存在，并可以填充表单的域，甚至可以验证一个假想的启用 Ajax 的 UI
与我们预期的工作方式一样。（有关 WebTest 和 HTMLUnit 的链接请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>。）</p>
<p>为了进一步简化 Web 的测试，Cargo（请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>）对 Tomcat 的启动和停止（分别在运行 WebTest 测试之前和之后）进行了自动化。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="2">理由 2：集成</a></p>
<p>正如我在本文简介中提到的一样，很多开放源码库都已经预先集成到 AppFuse 中了。它们可以分为以下几类：
</p>
<ul>
    <li><strong>编译、报告和代码生成：</strong>Ant、Ant Contrib Tasks、Checkstyle、EMMA、Java2Html、PMD 和 Rename Packages</li>
    <li><strong>测试框架：</strong>DbUnit、Dumbster、jMock、JUnit 和 Canoo WebTest</li>
    <li><strong>数据库驱动程序：</strong>MySQL 和 PostgreSQL</li>
    <li><strong>持久性框架：</strong>Hibernate 和 iBATIS</li>
    <li><strong>IoC 框架：</strong>Spring</li>
    <li><strong>Web 框架：</strong>JSF、Spring MVC、Struts、Tapestry 和 WebWork</li>
    <li><strong>Web 服务：</strong>XFire</li>
    <li><strong>Web 工具：</strong>Clickstream、Display Tag、DWR、JSTL、SiteMesh、Struts Menu 和 URL Rewrite Filter</li>
    <li><strong>Security：</strong>Acegi Security</li>
    <li><strong>JavaScript 和 CSS：</strong>Scriptaculous、Prototype 和 Mike Stenhouse 的 CSS Framework</li>
</ul>
<p>除了这些库之外，AppFuse 还使用 Log4j 来记录日志，使用 Velocity 来构建 e-mail 和菜单模板。Tomcat
可以支持最新的开发，我们可以使用 1.4 或 5 版本的 Java 平台来编译或构建程序。我们应该可以将 AppFuse 部署到任何 J2EE
1.3 兼容的应用服务器上；这已经经过了测试，我们知道它在所有主要版本的 J2EE 服务器和所有主要的 servlet 容器上都可以很好地工作。</p>
<p>图 3 给出了上面创建的 <em>devworks</em> 项目的 lib 目录。这个目录中的 lib.properties 文件控制了每个依赖性的版本号，这意味着我们可以简单地通过把这些包的新版本放到这个目录中并执行诸如 <code>ant test-all -Dspring.version=2.0</code> 之类的命令来测试这些包的新版本。</p>
<br />
<a name="fig3"><strong>图 3. 项目依赖性</strong></a><br />
<img alt="AppFuse 项目依赖性" src="http://www.ibm.com/developerworks/cn/java/j-appfuse/project_lib_directory.jpg" height="598" width="197" />
<br />
<p>预先集成这些开放源码库可以在项目之初极大地提高生产效率。尽管我们可以找到很多文档介绍如何集成这些库，但是定制工作示例并简单地使用它来开发应用程序要更加简单。</p>
<p>除了可以简化 Web 应用程序的开发之外，AppFuse 让我们还可以将 Web 服务简单地集成到自己的项目中。尽管 XFire 也在 AppFuse 下载中一起提供了，不过如果我们希望，也可以自己集成 Apache Axis（请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a> 中有关 Axis 集成的教程）。另外，Spring 框架和 XFire 可以一起将服务层作为 Web 服务非常简单地呈现出来，这就为我们提供了开发面向服务架构的能力。</p>
<p>另外，AppFuse 并不会将我们限定到任何特定的 API
上。它只是简单地对可用的最佳开放源码解决方案重新进行打包和预先集成。AppFuse 中的代码可以处理这种集成，并实现了 AppFuse
的基本安全性和可用性特性。只要可能，就会减少代码，以便向 AppFuse 的依赖框架添加一个特性。例如，AppFuse 自带的 Remember
Me 和 SSL 切换特性最近就因为类似的特性而从 Acegi Security 中删除了。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="3">理由 3：自动化</a></p>
<p>Ant 使得简化了从编译到构建再到部署的自动化过程。Ant 是 AppFuse 中的一等公民，这主要是因为我发现在命令行中执行操作比从 IDE 中更加简单。我们可以使用 Ant 实现编译、测试、部署和执行任何代码生成的任务。</p>
<p>尽管这种能力对于有些人来说非常重要，但是它并不适用于所有的人。很多 AppFuse 用户目前都使用 Eclipse 或 Intellij
IDEA 来构建和测试自己的项目。在这些 IDE 中运行 Ant 的确可以工作，但是这样做的效率通常都不如使用 IDE 内置的 JUnit
支持来运行测试效率高。</p>
<p>幸运的是，AppFuse 支持在 IDE 中运行测试，不过管理这种特性对于 AppFuse 开发人员来说就变得非常困难了。最大的痛苦在于
XDoclet 用来生成 Hibernate 映射文件和 Web 框架所使用的一些工件（例如 ActionForms 和 Struts 使用的
struts-config.xml）。IDE 并不知道需要生成的代码，除非我们配置使用 Ant 来编译它们，或者安装了一些可以认识
XDoclet 的插件。</p>
<p>这种对知识的缺乏是 AppFuse 2.0 切换到 JDK 5 和 Maven 2 上的主要原因。JDK 5、注释和 Struts 2
将让我们可以摆脱 XDoclet。Maven 2 将使用这些生成的文件和动态类路径来生成 IDE
项目文件，这样对项目的管理就可以进行简化。目前基于 Ant 的编译系统已经为不同的层次生成了一些工件（包括
dao.jar、service.jar 和 webapp.war），因此切换到 Maven 的模型上应该是一个非常自然的调整。</p>
<p>除了 Ant 之外（它对于编译、测试、部署和报告具有丰富的支持），对于 CruiseControl 的支持也构建到了 AppFuse
中。CruiseControl 是一个 Continuous Integration
应用程序，让我们可以在源代码仓库中代码发生变化时自动运行所有的测试。extras/cruisecontrol 目录包含了我们为基于
AppFuse 的项目快速、简单地设置 Continuous Integration 时所需要的文件。</p>
<p>设置 Continuous Integration 是软件开发周期中我们首先要做的事情之一。它不但激发程序员去编写测试用例，而且还通过 &#8220;You broke the build!&#8221; 游戏促进了团队之间的合作和融合。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="4">理由 4：安全特性和可扩展性</a></p>
<p>AppFuse 最初是作为我为 Apress 编写的书籍 <em>Pro JSP</em>
中示例应用程序的一部分开发的。这个示例应用程序展示了很多安全特性和用于简化 Struts 开发的特性。这个应用程序中的很多安全特性在 J2EE
的安全框图中都不存在。使用容器管理认证（CMA）的认证方法非常简单，但是 Remember Me、密码提示、SSL
切换、登记和用户管理等功能却都不存在。另外，基于角色的保护方法功能在非 EJB 环境中也是不可能的。</p>
<p>最初，AppFuse 使用自己的代码和用于 CMA 的解决方案完全实现了这些特性。我在 2004 年年初开始学习 Spring
时就听说过有关 Acegi Security 的知识。我对 Acegi 所需要的 XML 的行数（175）与 web.xml 中所需要的 CMA
的行数（20）进行了比较，很快就决定丢弃 Acegi 了，因为它太过复杂了。</p>
<p>一年半之后 —— 在为另外一本书 <em>Spring Live</em> 中编写了一章有关使用 Acegi Security 的内容之后 —— 我就改变了自己的想法。Acegi <em>的确</em>（目
前仍然）需要很多 XML，但是一旦我们理解了这一点，它实际上是相当简单的。当我们最终作出改变，使用 Acegi Security
的特性来全部取代 AppFuse 的特性之后，我们最终删除了大量的代码。类之上的类都已经没有了，&#8220;Acegi handles that now&#8221;
中消失的部分现在全部进入了 CVS 的 Attic 中了。</p>
<p>Acegi Security 是 J2EE 安全模型中曾经出现过的最好模型。它让我们可以实现很多有用的特性，这些特性在 Servlet
API 的安全模型中都不存在：认证、授权、角色保护方法、Remember Me、密码加密、SSL
切换、用户切换和注销。它让我们还可以将用户证书存储到 XML 文件、数据库、LDAP 或单点登录系统（例如 Yale 的 Central
Authentication Service (CAS) 或者 SiteMinder）中。</p>
<p>AppFuse 对很多与安全性相关的特性的实现从一开始都是非常优秀的。现在 AppFuse 使用了 Acegi Security，这些特性
—— 以及更多特性 —— 都非常容易实现。Acegi 有很多地方都可以进行扩充：这是它使用巨大的 XML
配置文件的原因。正如我们已经通过去年的课程对 Acegi 进行集成一样，我们已经发现对很多 bean 的定义进行定制可以更加紧密地与
AppFuse 建立联系。</p>
<p>Spring IoC 容器和 Acegi Security 所提供的简单开发、容易测试的代码和松耦合特性的组合是 AppFuse
是这么好的一种开发平台的主要原因。这些框架都是不可插入的，允许生成干净的可测试代码。AppFuse
集成了很多开放源码项目，依赖注入允许对应用程序层进行简单的集成。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="5">理由 5：使用 AppGen 生成代码</a></p>
<p>有些人会将代码生成称为<em>代码气味的散播（code smell）</em>。在他们的观点中，如果我们需要生成代码，那么很可能就会做一些错事。我倾向于这种确定自己代码使用的模式和自动化生成代码的能力应该称为<em>代码香味的弥漫（code perfume）</em>。如果我们正在编写类似的 DAO、管理器、操作或控件，并且不想为它们生成代码，那么这就需要根据代码的气味来生成代码。当然，当语言可以为我们提供可以简化任务的特性时，一切都是那么美好；不过代码生成通常都是一个必需 —— 通常其生产率也非常高 —— 的任务。</p>
<p>AppFuse 中提供了一个基于 Ant 和 XDoclet 的代码生成工具，名叫 <em>AppGen</em>。默认情况下，常见的 DAO 和管理器都可以允许我们对任何普通老式 Java 对象（POJO）进行 CRUD 操作，但是在 Web 层上这样做有些困难。AppGen 有几个特性可以用来执行以下任务：</p>
<ul>
    <li>（使用 Middlegen 和 Hibernate 工具）从数据库表中生成 POJO</li>
    <li>从 POJO 生成 UI</li>
    <li>为 DAO、管理器、操作/控制器和 UI 生成测试</li>
</ul>
<p>在运行 AppGen 时，您会看到提示说 AppGen 要从数据库表或 POJO 中生成代码。如果在命令行中执行 <code>ant install-detailed</code>，AppGen 就会安装 POJO 特定的 DAO、管理器以及它们的测试。运行 <code>ant install</code> 会导致 Web 层的类重用通用的 DAO 和默认存在的管理器。</p>
<p>为了阐述 AppGen 是如何工作的，我们在 <em>devworks</em> MySQL 数据库中创建了如清单 2 所示的表：</p>
<br />
<a name="listing2"><strong>清单 2. 创建一个名为 cat 的数据库表</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre>    create table cat (<br />
            cat_id int(8) auto_increment,<br />
            color varchar(20) not null,<br />
            name varchar(20) not null,<br />
            created_date datetime not null,<br />
            primary key (cat_id)<br />
            ) type=InnoDB;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在 extras/appgen 目录中，运行 <code>ant install-detailed</code>。这个命令的输出结果对于本文来说实在太长了，不过我们在清单 3 中给出了第一部分的内容：</p>
<br />
<a name="listing3"><strong>清单 3. 运行 AppGen 的 install-detailed 目标</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre>$ ant install-detailed<br />
            Buildfile: build.xml<br />
            <br />
            init:<br />
            [mkdir] Created dir: /Users/mraible/Work/devworks/extras/appgen/build<br />
            [echo] <br />
            [echo] +-------------------------------------------------------+<br />
            [echo] |             -- Welcome to the AppGen! --              |<br />
            [echo] |                                                       |<br />
            [echo] | Use the "install" target to use the generic DAO and   |<br />
            [echo] | Manager, or use "install-detailed" to general a DAO   |<br />
            [echo] | and Manager specifically for your model object.       |<br />
            [echo] +-------------------------------------------------------+<br />
            <br />
            [input] Would you like to generate code from a table or POJO? (table,pojo)<br />
            table<br />
            [input] What is the name of your table (i.e. person)?<br />
            cat<br />
            [input] What is the name, if any, of the module for your table (i.e. organization)?<br />
            <br />
            [echo] Running Middlegen to generate POJO...<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>要对 cat 表使用这个新生成的代码，我们需要修改
src/dao/com/ibm/dao/hibernate/applicationContext-hibernate.xml，来为
Hibernate 添加 Cat.hbm.xml 映射文件。清单 3 给出了我们修改后的 <code>sessionFactory</code> bean 的样子：</p>
<br />
<a name="listing4"><strong>清单 4. 将 Cat.hbm.xml 添加到 sessionFactory bean 中</strong></a><br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>
            <pre>    &lt;bean id="sessionFactory" class="..."&gt;<br />
            &lt;property name="dataSource" ref="dataSource"/&gt;<br />
            &lt;property name="mappingResources"&gt;<br />
            &lt;list&gt;<br />
            &lt;value&gt;com/ibm/model/Role.hbm.xml&lt;/value&gt;<br />
            &lt;value&gt;com/ibm/model/User.hbm.xml&lt;/value&gt;<br />
            &lt;value&gt;com/ibm/model/Cat.hbm.xml&lt;/value&gt;<br />
            &lt;/list&gt;<br />
            &lt;/property&gt;<br />
            ...<br />
            &lt;/bean&gt;<br />
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在运行 <code>ant setup deploy</code> 之后，我们就应该可以在部署的应用程序中对 cat 表执行 CRUD 操作了：</p>
<br />
<a name="fig4"><strong>图 4. Cat 列表</strong></a><br />
<img alt="所生成的主屏幕" src="http://www.ibm.com/developerworks/cn/java/j-appfuse/cat_list.jpg" height="379" width="572" />
<br />
<br />
<a name="fig5"><strong>图 5. Cat 表单</strong></a><br />
<img alt="所生成的详细屏幕" src="http://www.ibm.com/developerworks/cn/java/j-appfuse/cat_detail.jpg" height="379" width="572" />
<br />
<p>我们在上面的屏幕快照中看到的记录都是作为代码生成的一部分创建的，因此现在就有测试数据了。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="6">理由 6：文档</a></p>
<p>我们可以找到 AppFuse 各个风味的教程，并且它们都以 6 种不同的语言给出了：中文、德语、英语、韩语、葡萄牙语和西班牙语。使用<em>风味（flavor）</em>
一词，我的意思是不同框架的组合，例如 Spring MVC 加上 iBATIS、Spring MVC 加上 Hibernate 或 JSF
加上 Hibernate。使用这 5 种 Web 框架和两种持久框架，可以有好几种组合。有关它们的翻译，AppFuse 为自己的默认特性提供了 8
种翻译。可用语言包括中文、荷兰语、德语、英语、法语、意大利语、葡萄牙语和西班牙语。</p>
<p>除了核心教程之外，还添加了很多教程（请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>） 来介绍与各种数据库、应用服务器和其他开放源码技术（包括 JasperReports、Lucene、Eclipse、Drools、Axis 和 DWR）的集成。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="7">理由 7：社区</a></p>
<p>Apache 软件基金会对于开放源码有一个有趣的看法。它对围绕开放源码项目开发一个开放源码社区最感兴趣。它的成员相信如果社区非常强大，那么产生高质量的代码就是一个自然的过程。下面的内容引自 Apache 主页：</p>
<blockquote>
&#8220;我们认为自己不仅仅是一组共享服务器的项目，而且是一个开发人员和用户的社区。&#8221;
</blockquote>
<p>AppFuse 社区从 2003 年作为 SourceForge 上的一个项目（是 struts.sf.net
的一部分）启动以来，已经获得了极大的增长。通过在 2004 年 3 月转换到 java.net 上之后，它已经成为这里一个非常流行的项目，从
2005 年 1 月到 3 月成为访问量最多的一个项目。目前它仍然是一个非常流行的项目（有关 java.net 项目统计信息的链接，请参看 <a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources">参考资料</a>），不过在这个站点上它正在让位于 Sun 赞助的很多项目。</p>
<p>在 2004 年年末，Nathan Anderson 成为继我之后第一个提交者。此后有很多人都加入了进来，包括 Ben
Gill、David Carter、Mika G?ckel、Sanjiv Jivan 和 Thomas
Gaudin。很多现有的提交者都已经通过各种方式作出了自己的贡献，他们都帮助 AppFuse 社区成为一个迅速变化并且非常有趣的地方。</p>
<p>邮件列表非常友好，我们试图维护这样一条承诺 &#8220;没有问题是没有人理会的问题&#8221;。我们的邮件列表归档文件中惟一一条 &#8220;RTFM&#8221;
是从用户那里发出的，而不是从开发者那里发出的。我们绝对信奉 Apache 开放源码社区的哲学。引用我最好的朋友 Bruce Snyder
的一句话，&#8220;我们为代码而来，为人们而留下&#8221;。目前，大部分开发者都是用户，我们通常都喜欢有一段美妙的时间。另外，大部分文档都是由社区编写的；因此，
这个社区的知识是非常渊博的。</p>
<br />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br />
            <img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td>
        </tr>
    </tbody>
</table>
<table align="right" cellpadding="0" cellspacing="0">
    <tbody>
        <tr align="right">
            <td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br />
            <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br />
                        </td>
                        <td align="right" valign="top"><a href="http://www.ibm.com/developerworks/cn/java/j-appfuse/index.html#main" class="fbox"><strong>回页首</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="8">结束语</a></p>
<p>我们应该尝试使用 AppFuse 进行开发，这是因为它允许我们简单地进行测试、集成、自动化，并可以安全地生成 Web 应用程序。其文档非常丰富，社区也非常友好。随着其支撑框架越来越好，AppFuse 也将不断改进。</p>
<p>从 AppFuse 2.0 开始，我们计划迁移到 JDK 5（仍然支持部署到 1.4）和 Maven 2 上去。这些工具可以简化使用
AppFuse 的开发、安装和升级。我们计划充分利用 Maven 2 的功能来处理相关依赖性。我们将碰到诸如
appfuse-hibernate-2.0.jar 和 appfuse-jsf-2.0.jar 之类的工件。这些工件都可以在 pom.xml
文件中进行引用，它们负责提取其他相关依赖性。除了在自己的项目中使用 AppFuse 基类之外，我们还可以像普通的框架一样在 JAR
中对这些类简单地进行扩展，这应该会大大简化它的升级过程，并鼓励更多用户将自己希望的改进提交到这个项目中。</p>
<p>如果没有其他问题，使用 AppFuse 可以让您始终处于 Java Web 开发的技术前沿上 —— 就像我们一样！</p>
<br />
<br />
<p><a name="resources">参考资料 </a></p>
<strong>学习</strong><br />
<ul>
    <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/java/library/j-appfuse/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j" target="_blank">英文原文</a> 。<br />
    <br />
    </li>
    <li>
    <a href="http://appfuse.org/">AppFuse</a>：该项目的主页。
    <br />
    <br />
    </li>
    <li>
    <a href="http://appfuse.org/demos.html">AppFuse Demos</a>：查看演示和视频。
    <br />
    <br />
    </li>
    <li>
    <a href="http://jroller.com/page/mrdon?entry=unification_struts_action_and_jsf">Struts 2 和 JSF</a>：了解为什么要将这些技术放到一起工作。
    <br />
    <br />
    </li>
    <li>
    <a href="http://java.sun.com/blueprints/code/projectconventions.html">Sun 的 J2EE 项目目录结构指南</a>：AppFuse 非常接近于这些指南。
    <br />
    <br />
    </li>
    <li>
    <a href="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">Maven 的 Standard Directory Layout</a>：AppFuse 2.0 将转换到这个目录结构上。
    <br />
    <br />
    </li>
    <li><a href="http://appfuse.org/wiki/QuickStart.html">AppFuse 快速入门指南</a>：快速入门并使用 AppFuse。
    <br />
    <br />
    </li>
    <li><a href="http://appfuse.org/wiki/Articles.html">AppFuse 教程</a>：深入学习更多有关使用 AppFuse 的知识。
    <br />
    <br />
    </li>
    <li>
    <a href="http://raibledesigns.com/wiki/AppFuseAxis.html">Apache Axis 集成</a>：如何将 Apache Axis 集成到自己的 AppFuse 项目中。
    <br />
    <br />
    </li>
    <li>Java.net 项目状态：请查看 2005 年 <a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=January">1 月</a>、<a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=February">2 月</a> 和 <a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=March">3 月</a> 的动态。还可以查看 <a href="http://community.java.net/projects/top.csp">java.net 上的最佳项目 </a>。
    <br />
    <br />
    </li>
</ul>
<br />
<strong>获得产品和技术</strong><br />
<ul>
    <li>
    <a href="https://appfuse.dev.java.net/servlets/ProjectDocumentList">AppFuse on java.net</a>：下载不同风味的 AppFuse。
    <br />
    <br />
    </li>
    <li>
    <a href="http://opensymphony.com/webwork">WebWork</a>：了解这个易于使用的 Web 框架。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.dbunit.org/">DbUnit</a>：查看更多有关 JUnit 扩展的内容。
    <br />
    <br />
    </li>
    <li>
    <a href="http://www.jmock.org/">jMock</a>：创建动态仿真对象来简化真正的单元测试。
    <br />
    <br />
    </li>
    <li>
    <a href="http://webtest.canoo.com/">Canoo WebTest</a>：自动化 Web 应用程序的 UI 测试。
    <br />
    <br />
    </li>
    <li>
    <a href="http://htmlunit.sf.net/">HtmlUnit</a>：WebTest 的优秀 JavaScript 支持背后的基础。
    <br />
    <br />
    </li>
    <li>
    <a href="http://cargo.codehaus.org/">Cargo</a>：自动启动和停止容器。
    <br />
    <br />
    </li>
    <li>
    <a href="http://greenbox.dev.java.net/">Greenbox</a>：一种代码生成框架。
    <br />
    <br />
    </li>
</ul>
<br />
<strong>讨论</strong><br />
<ul>
    <li>
    <a href="http://www.nabble.com/AppFuse-f2369.html">AppFuse 论坛</a>：与同行开发人员交流技巧。</li>
</ul>
<img src ="http://www.blogjava.net/caizh2009/aggbug/327771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-08-02 17:38 <a href="http://www.blogjava.net/caizh2009/archive/2010/08/02/327771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appfuse</title><link>http://www.blogjava.net/caizh2009/archive/2010/03/05/314609.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Fri, 05 Mar 2010 06:40:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/03/05/314609.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/314609.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/03/05/314609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/314609.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/314609.html</trackback:ping><description><![CDATA[<span style="color: red;">AppFuse是一个集成了众多当前最流行开源框架与工具(包括Hibernate、ibatis、Struts、Spring、DBUnit、Ant、Log4J、Struts Menu、Xdoclet、SiteMesh、OSCache、JUnit、JSTL)于一身的Web开发框架。AppFuse提供了Web系统开发过程中都需要开发的一些功能，如登陆、用户密码加密，用户管理、根据不同的用户可以展现不同的菜单.J2EE开发者也可以在此基础上开发加入自己的功能模块。利用这个框架可以大幅度的提高开发速度。</span> <br />
<p>转自:http://blog.chinaunix.net/u/11409/showart_436247.html<br />
</p>
<p><a href="http://blog.csdn.net/changzhang/category/369570.aspx">http://blog.csdn.net/changzhang/category/369570.aspx</a>可参考这个网址<br />
AppFuse是一个集成了当前最流行的Web应用框架的一个更高层次的Web开发框架，也可以说是一个Web开发基础平台，它与它所集成的各种框架相比，它提供了一部分所有Web系统开发过程中都需要开发的一些功能，如登陆、用户密码加密，用户管理、根据不同的用户可以展现不同的菜单，可以自动生成 40%-60%左右的代码，自带了默认的一些在CSS中设定的样式，使用这些样式能很快的改变整个系统的外观，还有自动化测试的功能。</p>
<p>它最大的价值就是为我们提供了一个Web开发的新的方式和思路，尽管这些技术在国外都已进很流行了，但在国内能够将Hibernate、Struts、 Spring、DBUnit、Ant、Log4J、Struts Menu、Xdoclet、SiteMesh、Velocity、JUnit、JSTL、WebWork这些技术集成到一个框架中的还不多见，所以即使不使用它的全部功能，它也给我们提供了一个很好的借鉴、学习的机会。</p>
<p>通过关注AppFuse，我们可以看到目前国外的主流开发都使用了哪些技术，开发方式是什么样的，可能达到什么样的结果，而在以前，是很少能够看到这样完整的例子的。</p>
<p>AppFuse的另一个启示是：我们可以依靠开源软件的功能降低开发成本，而且可以阅读开源软件的代码提高所在团队的整体实力。</p>
<p>AppFuse 的作者 Matt Raible是当今开源世界一个比较活跃的开发者，它是AppFuse、Struts Menu的作者，也是XDoclet、DisplayTag等一些著名开源项目的积极参与者，《Hibernate In Action》的作者就在感谢的名单里面提到他，XDoclet的下载版本中所带的Hibernate标签部分的例子就是他写的，他还是2004年 Apache技术年会的主讲人之一。</p>
<p>但是通过2个月的实际学习和使用，我也遇到一系列的问题，因为AppFuse是将其他的一些类库或者框架集成在一起的，集成的技术众多，而且有一些技术在国内甚至很少有人知道，资料也比较少，所以虽然作者经过了一些测试，但都是基于英文编码的，而对于中文编码来说，还潜在的存在着一些问题，虽然不是AppFuse的问题，但却降低了开发速度，下面是我在开发过程中遇到过的问题，有些解决了，有些还没有解决：<br />
一．Struts<br />
1． AppFuse中默认的MVC框架是Struts，而且使用的是LookupDispatchAction，并且使用的是按钮（button），在XP下用IE浏览效果还可以，但如果在2000或者98下，就使外观很难看，而且当时我还遇到一个问题：如果按钮显示中文，则在DisplayTag中翻页失灵，而且报错，后来我把BaseAction的相关方法改变了，才可以使用，因为国内的客户都比较重视界面，所以后来我将那些按钮都改成图片了，当然也要添加一些方法了，有点麻烦！<br />
2． Struts中的标签如今推荐使用的只有html部分的标签了，其他的标签或者可以使用JSTL替代，或者已经不推荐使用了，而且AppFuse中推荐使用JSTL，而JSTL和struts的标签的联合使用时，需要的不是&lt;html:标签&gt;，而是&lt;html-el:标签&gt;，这个问题曾经困扰了我整整2天。<br />
3． Struts的Validation的校验规则并不完善，比如如果使用客户端的javascript校验，则在邮箱中输入汉字根本校验不出来，到了服务器端报错。<br />
4．最严重的问题是AppFuse生成的Struts的validation.xml文件中有许多多余的&#8220;.&#8221;，如果你去掉了，常常在执行ant的 deploy任务时又恢复原样。这样是提交表单的时候经常会报javascript的脚本错误或者缺少对象或者缺少value，所以我会手工的修改这个文件，然后把修改后的文件备份，当重新生成有错误的文件时，我会用备份的没有错误的文件去覆盖。<br />
5． Struts的validatioin对于使用同一个FormBean的Action的校验方式比较复杂。（待解决）。<br />
二．Hibernate<br />
1． Hibernate是现在受到越来越多的人推崇的一个ORM工具（框架、类库），它将我们从繁琐的使用JDBC的开发过程中解放出来，但同时也带来了新的问题，如学习曲线，执行效率，数据库设计优化，还有最重要的灵活性。Hibernate不是一个很容易上手的东西，要完全驾驭它还需要读很多资料，但好的资料却很少。<br />
2． 使用Xdoclet可以很方便的生成Hibernate中的持久类的配置文件（*.hbm.xml）,但对一些特殊的映射却无能为力，如使用序列的id生成规则，序列的名字没有地方写，所以也只好先利用它生成主要的内容，然后手工修改。<br />
3． 同样还是id的生成策略问题，如果使用序列、hilo等需要一些数据库机制支持的策略时，schemaExport并不能自动生成序列或者保存当前id的表，这项工作仍然要手工解决。<br />
4． Hibernate中提供了几种关联，一对一、一对多、多对多，但对于怎样调整效率却没有一个很明确的提示，还要根据情况判定，这就带来和一些弹性的设计。<br />
5． Hibernate中可以选择的操作数据库的方式有3种，其中HQL功能最强大，但有些功能使用标准查询可能会更方便，但会有一些限制，所以虽然它很灵活，但易用性不如JDBC好。<br />
三．Spring<br />
在AppFuse的过程中，Spring完全隐藏在幕后，除了一些配置外，几乎感觉不到它的存在，所以我在使用它的过程中并没有遇到什么麻烦，这里只是简单的介绍一下它在AppFuse中起到的作用。<br />
1． Spring在AppFuse中起到的主要作用是对Hibernate的Session和事务的管理，利用Spring封装的Hibernate模板类，我们大大地减少了实现DAO的代码行数。<br />
2． Spring还起到了连接映射文件和类之间的关联，及接口和实现类之间的关联，这些都依赖于Spring的IoC的机制的实现。<br />
3． 对于字符进行编码和解码部分用到了Spring自带的Filter，只需要在配置文件中配置就好了。</p>
<p>四．SiteMesh<br />
SiteMesh是一个基于Decorator模式的技术，它可以修饰返回的网页文件，它的工作方式受到越来越多的人的推崇，这点从Manning出版的一些技术书籍中可以看出来。<br />
我在使用SiteMesh的过程中并不顺利，我参考了《Java Open Source Programming》，这本书中说SiteMesh在默认的情况下不对下载文件进行装饰，但我在下载文件时发现，我的文件内容被丢弃了，取而代之的是 SiteMesh的模板的内容，后来我通过修改SiteMesh的配置文件解决了这个问题，但感觉还有一些不太清楚的地方需要学习。</p>
<p>五．DisplayTag<br />
DisplayTag 是一个优秀的显示内容的标签，从SourceForge的访问量来看，它是很活跃的项目，仅次于Ant、Hibernate、Xdoclet等几个著名的项目，我总结，它的主要功能有4项：显示、分页、排序、将显示的数据写入指定类型的文件中，然后下载。<br />
1． 据我使用的情况看，我只使用了分页和显示的功能，因为当时我没有很好的解决中文编码的问题，所以排序会有问题，直到昨天，我在朋友的帮助下解决了这个问题，至此我可以放心使用的功能又增加了排序(我昨天简单的测试了一下是可以的)。</p>
<p>2． 但对于将显示的内容生成到一个指定格式的文件中的功能却有着很多缺陷，如：<br />
（1） 生成的文件中只有显示的数据，那些没有显示在界面上的的数据，则不会被写到文件中。<br />
（2） 如果修改了DisplayTag的显示的内容，比如添加一列，在这列中的内容不是字符，而是HTML的标签，则生成的文件只有这些HTML标签，而没有数据。<br />
（3） 即使DisplayTag中没有我们定制的HTML脚本，生成的文件偶尔也有问题，比如：它会把&#8220;007&#8221;生成为&#8220;7&#8221;，把字符串自动的转换为整型值。有时候还生成空白内容的文件。<br />
（4） DisplayTag生成的Excel文件兼容性不好，有时在Excel2003中不能正常打开，或者在XP下打开报错。<br />
后来，我看了作者写的《Spring Live》，书中说如果想实现稳定的Excel，推荐使用POI，于是我使用POI生成Excel，稳定性和兼容性都不错。</p>
<p>六．DBUnit<br />
DBUnit是一个可以被Ant集成的向数据库中添加数据和备份数据的一个类库，配置很方便，因为AppFuse已经集成好了，所以使用也很容易。<br />
但是如果你使用EditPlus之类的工具手工修改了AppFuse生成的内容，则执行Ant的setup、setup-db或者deploy的任务时，常常报错，说无效的格式，这是因为这个被手工修改的文件再次被AppFuse执行后，它的第一行的文件声明的前几个字母是无效的，是因为本地的字符集编码的原因而引起了乱码，如果把这几个无效的字母去掉，问题就解决了。</p>
<p>七．Struts Menu<br />
Struts Menu也是AppFuse的作者开发的一个开源软件，它可以根据配置文件读取当前用户可以使用的功能菜单，这个功能是我一直以来都想要的，我也找到了一些代码，但实现的都不如这个完善，没什么好说的，使用简单，配置容易，很好的解决了我的问题。<br />
问题是我只使用了AppFuse提供的2个角色，对于多个角色的实验我还没有做。</p>
<p>八．XDoclet<br />
在AppFuse中，使用Xdoclet生成了几乎一切的配置文件：Struts-config.xml、web.xml、validation.xml、*.hbm.xml等文件，如果使用AppGen的话，还会生成更多的文件，这一切都是使用Xdoclet实现的。<br />
问题是我在Struts部分提到的，生成的Validation.xml文件中会多生成一个&#8220;.&#8221;，另外在生成资源文件时也会多生成一个&#8220;.&#8221;，目前我没有很好的阅读这段代码，不知道是不是Xdoclet的问题。</p>
<p>九．Ant<br />
Ant并没有什么问题，但在执行作者写的Ant任务的时候，有一些任务不能正常执行，比如，运行模拟对象测试的任务，作者也在1.7版本的修复列表中提到以前版本有些ant任务不能执行，在1.7中修改了一些ant任务，使他们能够正常的执行了。<br />
实际上，我们如果使用AppGen进行开发的话，使用的任务一般不超过8个。</p>
<p>十．JSTL<br />
JSTL 是个好东西，我常用的有&lt;c:&gt;和&lt;fmt:&gt;部分的标签，但是如果使用JSTL进行逻辑判断，我并没有感觉比使用JSP的代码块优雅多少。另外，熟悉JSTL也需要一段时间，我就经历了面对着JSP页面不知道该怎么写JSTL语法的困境。当然，AppFuse中使用的基本都是 JSTL，包括向DisplayTag传递显示的数据，使用的都是JSTL语法，这方面的资料挺多，我参考的是电子工业出版社出的《JSP2.0技术》，说的很详细。</p>
<p>十一.Tomcat<br />
你也许会说：&#8220;Tomcat就不用说了吧？&#8221;，是的，Tomcat一般都会使用，但是 ―――――――――――――Tomcat5和Tomcat4.X对于中文编码使用了不同的机制，这个问题困扰了我好久，我解决了页面上写入汉字显示乱码的问题，我也曾经以为DisplayTag对汉字不能排序，也不能正常分页是因为DisplayTag的开发者都是老外，是因为他们没有考虑中文的关系的原因。<br />
直到昨天，我才知道这一切都是因为Tomcat5对汉字编码的实现的方式和Tomcat4不一样的原因，如果感兴趣，可以看看这个帖子： http://www.javaworld.com.tw/jute/post/view?bid=9&amp;id=44042&amp;sty=1&amp;tpg=1&amp;age=0</p>
<p>十二.JavaScript<br />
JavaScript简单易学，但想运用自如就不太容易了。AppFuse中嵌入了几个js文件，里面包含了许多函数，值得我们好好的研究一下，比如，如果有一个必填字段没有填写，AppFuse会自动的聚焦在那个input上，类似的小技巧有很多，你可以自己去翻看。<br />
但AppFuse 自带的JavaScript脚本有一个Bug，就是当DisplatyTag中没有可以显示的数据时，你用鼠标单击，它会报JavaScript错误，你仔细研究一下function highlightTableRows(tableId) 就知道了：我的解决办法是在location.href = link.getAttribute("href");前面添加一行判断：if (link != null)。</p>
<p>十三.资源文件国际化<br />
对于Struts和DisplayTag都涉及到资源文件国际化AppFuse1.6.1很好的解决了Struts资源映射文件国际化的问题，你只需要在对应本国语言的资源文件中写入汉字，Ant中有一项执行native2ascii的任务，AppFuse自动的为你进行了资源文件的编码转换，而对于 DisplayTag的资源文件问题，还要自己执行native2ascii命令，为了避免每次都输入一串命令，我用Delphi写了个小工具，可视化的选择资源文件，点击按钮自动执行该命令，底层依赖于JDK。</p>
<p><br />
经过2个多月的学习，我感觉这个框架非常不错，它为我以后的项目开发指出了一个新的方向，但如果想很熟练的使用这个框架进行开发，至少要对以下几种技术比较熟练：Struts(或者WebWork、Spring及其他的已经整合进来的MVC框架)、Hibernate（或者ibatis）、JSTL，当然其他的技术至少也要知道一点，否则遇到问题都不知道出在哪里。</p>
<p><br />
目前我还没有解决的问题有：<br />
1． 如何在翻页的时候才读取下面的数据？<br />
2． 怎样对使用同一个FormBean的多个Form进行客户端校验？<br />
3． 怎样优化Hibernate的效率？《Hibernate In Action》中提供了多种策略，有些时候应该使用lazy，有些时候应该使用outer-join。<br />
4．在什么时机生成导出文件？目前我是在查询的Action中同时生成了导出文件，否则，到了下一页，我就不知道查询条件了，当然，如果把拼装后的HQL存储在Session或者Hidden中也可以解决这个问题，但是这样就破坏了DAO的封装，要把DAO封装后的HQL发送给Action，然后发送的到 Web界面层，所以目前我还在犹豫生成导出文件的时机选择在哪里？<br />
5． 什么时候应该自己获取数据库连接，执行native SQL？具体需要注意些什么？<br />
6． SiteMesh的模板优化？<br />
7． DisplayTag的底层实现？</p>
<p><br />
每个问题都比较棘手，要一个一个解决！</p>
<p>这个框架的优点是：如果熟悉了开发流程，可以大幅度的提高开发速度，如果业务不是很复杂，使用AppGen可以生成60%左右的代码，而且程序可维护性好，因为作者使用了多个设计模式对各个层面进行了封装，所以不同的模块代码风格出奇的一致，有利于开发人员快速上手，也有利于接收其他开发人员遗留的代码。</p>
<p>兔八哥<br />
2004-2-3下午15:51</p>
<p>++++++++++++++++++++</p>
<p>引用:<br />
有没有成功的项目同我们分享一下?</p>
<p>&nbsp;</p>
<p>我已经使用AppFuse开发了2个项目了，都是教育系统的，系统都不大，我一个人用实际开发一个月，因为是公司的项目，源码不好外发，但主要的东西都是一样的，对于AppFuse我也没有修改多少，否则，往新版本移植就会有问题了。<br />
我遇到的问题，能想起来的我都写下来了，如果有其他的问题，我们可以一起讨论。<br />
最近我有个朋友在使用WebWork的AppFuse版本进行开发，他遇到的问题和我基本差不多，有交流才有进步，呵呵！<br />
Very Happy</p>
<p>感谢楼上几位的热心解答，谢谢！</p>
<p>+++++++++++++++++++++++</p>
<p>引用:<br />
目前我还没有解决的问题有：<br />
1． 如何在翻页的时候才读取下面的数据？<br />
2． 怎样对使用同一个FormBean的多个Form进行客户端校验？<br />
3． 怎样优化Hibernate的效率？《Hibernate In Action》中提供了多种策略，有些时候应该使用lazy，有些时候应该使用outer-join。<br />
4．在什么时机生成导出文件？目前我是在查询的Action中同时生成了导出文件，否则，到了下一页，我就不知道查询条件了，当然，如果把拼装后的HQL存储在Session或者Hidden中也可以解决这个问题，但是这样就破坏了DAO的封装，要把DAO封装后的HQL发送给Action，然后发送的到 Web界面层，所以目前我还在犹豫生成导出文件的时机选择在哪里？<br />
5． 什么时候应该自己获取数据库连接，执行native SQL？具体需要注意些什么？<br />
6． SiteMesh的模板优化？<br />
7． DisplayTag的底层实现？</p>
<p><br />
1.关于翻页的问题，如果你刚开始使用AppFuse开发的话，推荐使用valuelist,它可以和Hibernate很好的集成，我的一个网友用的就是这个东西，虽然界面没有DisplayTag漂亮，但关于分页却不用你操太多的心，<br />
因为这几天天天开会，所以也没有做些技术实验，另一个朋友告诉我有一个老外把DisplayTag分页部分修改了，在JIRA上有源码下载，我下来了，还没有看，还有一个思路，就是分析DisplayTag的分页的格式，然后用Filter解析，然后把当前页号传入DAO，然后使用标准查询进行查询分页，但要对AppFuse的接口和方法添加参数，正在犹豫中，还有更简单的方法，直接在Session中放入当前的页号，每次都刷新，就不用Filter了，然后同样修改方法和接口。</p>
<p>2.对于Struts的使用同一个FormBean的多个Form进行客户端校验，在孙卫琴的Struts的书中已经提到了，即使她的方法不管用，也可以手写JavaScript来解决，只是我不愿意而已，如果别无他法，则只能如此了。</p>
<p>3. 优化Hibernate的效率，其实对我的程序来说问题不大，我的表比较少，基本只有3层的级联，而且对于数据字典和业务表之间的关联，我采用的是业务表到数据字典表的many-to-one，这样的单向关联比较简单，也能够满足我的要求，性能会好一点点，再加上分页功能，只查询当前也内容，然后参考《Hibernate In Action》的第七章的内容，提高接收效率应该是没有问题的。</p>
<p>4.关于到处文件的时机，我正在看关于模式的书籍，正在找答案，其实还有个简单的办法，就是把生成导出文件单独的实现，用户点击按钮才生产，当然这样就要把用户的查询条件记下来，当然也涉及到修改接口和方法了，AppFuse中，修改接口和方法很麻烦，如果代码生成后再修改，要改动很多处，所以前期设计很重要。</p>
<p>5.关于这一点，我一直在找一个硬性的标准，比如关联表超过多少个等等条件就应该自己获取数据库连接，但现在看来这也不是绝对的，如果能够大幅度提高效率，或者使用 native SQL可以减少工作量或者节省时间的话，那就可以使用，只是要对这种方式的利弊要有所了解，不幸的是，我还没有这样试过，试过的朋友请提供些建议，谢谢！</p>
<p>6.SiteMesh的优化，我看到一片文章，也是个老外写的，忘了出处，说SiteMesh对性能影响不大，可以放心使用，那我就暂时不考虑它了，呵呵。</p>
<p>7.DisplayTag的底层的原理我早就知道，而且它的文档的流程图也有，只是我需要知道更详细的实现细节，最近在读源码，应该很快就有结果了，如果我有好消息，会来这里把解决方案贴出来。</p>
<p><br />
上面的文字只是我目前的一些思路，因为天天开会，也没有做技术实验，还不知道可行的程度，但我想应该都可以实现，我只不过是在找更好的办法，如果你有任何好的思路或者建议，请不吝告知，谢谢，任何建议和意见都是受欢迎的，只是要详细些，不要拿些空洞的模式来敷衍我，呵呵，目前这样的&#8220;高手&#8221;不少，我有些受够了，呵呵 </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/changzhang/archive/2008/03/12/2172675.aspx</p>
<br />
<br />
<img src ="http://www.blogjava.net/caizh2009/aggbug/314609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-03-05 14:40 <a href="http://www.blogjava.net/caizh2009/archive/2010/03/05/314609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>