1          AppFuse: Start Your J2EE Web Apps

1  AppFuse: 开始你的J2EE web应用

by Matt Raible


The Birth of AppFuse

What Is AppFuse?

What Does the Future Hold?

AppFuse Light

How Do I Start Using It?


One of the hardest parts about J2EE development is getting started. There is an immense amount of open source tools for web app development. Making a decision on which technologies to use can be tough — actually beginning to use them can be even more difficult. Once you’ve decided to use Struts and Hibernate, how do you go about implementing them? If you look on the Hibernate site or the Struts site, you’ll probably have a hard time finding any information on integrating the two. What if you want to throw Spring into the mix? As a developer, the best way for me to learn is by viewing sample apps and tutorials that explain how to extend those applications. In order for me to learn (and remember) how to integrate open source technologies such as Hibernate, Spring, Struts, and Ant/XDoclet, I created AppFuse. The beauty of AppFuse is you can actually get started with Hibernate, Spring, and Struts without even knowing much about them. Using test-driven development, AppFuse and its tutorials will show you how to develop a J2EE web application quickly and efficiently.

J2EE开发来说,起步是一件最困难的事情之一。对于巨大数量的开源技术来说,决定选择哪些技术可能是很困难的实际上,对于他们的上手可能更加困难。假设你选择了StrutsHibernate,那么你如何去在一起使用他们。即使你去查找Hibernate主站或者Struts主站,你仍然难以找到关于如何整合两者的信息。假如你又再打算整合Spring又会如何?作为一个开发者,我认为最好的学习方法是浏览简单的示例程序和指南来解释如何扩展这些程序。为了我能够学习和记住如何集成像Hibernate, Spring, Struts, Ant/XDoclet这样的开源技术,我编写了AppFuseAppFuse的诱人之处就是你能够即刻开始使用Hibernate, Spring, and Struts却无需知道很多关于它们的知识。AppFuse和它的指南将告诉你如何快速有效的使用测试驱动方式开发一个J2EE web应用程序。


2          The Birth of AppFuse


In early 2002, I managed to land a contract where I was the lone developer. I was responsible for everything, from gathering requirements to database creation to DHTML on the web front end. While I’d done a lot of front-end work (Struts, HTML, etc.) over the years, the business layer and persistence layer were mostly new to me. So I searched and searched for J2EE patterns to do things the “right way” for my new client. I ended up implementing Business Delegates, DAOs, and ServiceLocators — many of them modeled after J2EE Blueprints. Towards the end of that contract, I was contracted to help write a book on JSP 2.0. The publisher was Wrox Press and the book was Professional JSP 2.0. I volunteered to write two chapters — one on Struts and one on web security. Note: in March 2003, Wrox went out of business and this book eventually became Pro JSP, Third Edition, published by Apress.

2002年初的时候,我得到了一份个人独立开发的合同,我要负责所有的事情,包括从收集需求到数据库创建和编写web前端的DHTML。虽然我做过多年前台的工作(Struts, HTML,等等),但是业务层和数据持久层的很多东西对我来说是不熟悉的。于是我不断的查找各种J2EE模式来以“正确的方法”满足我的新客户。我最终实现了Business Delegates, DAOs, and ServiceLocators –很多J2EE Blueprints中的模型。在那个合同的最后,我被约定去帮助写一本关于JSP2.0的书。出版商是Wrox Press,这本书的名字是Professional JSP 2.0我志愿编写了两章――一章是关于Struts而另一章是关于web安全。

注:在20033月,Wrox 停业,最终该书Apress出版,名为:Pro JSP, Third Edition

When you write a technical book, it’s helpful to use a sample app to demonstrate concepts. I was tired of reading books that had a throwaway sample app, so I wanted to develop something meaningful; something I could use after I was done writing. My initial thoughts were to write an application that would help you get started with Struts, and would use XDoclet to do a lot of the heavy lifting. It also had to have a lot of security features so I could use it for my chapter on web application security. I came up with the name struts-xdoclet and began developing my application.


After a couple of weeks, I decided that “struts-xdoclet” was too hard to say and renamed the project AppFuse. I developed the sample app for my Struts chapter using AppFuse and released it as Struts Resume. After publishing Struts Resume, I needed to extract the resume-specific stuff out of it to revert back to the generic “jumpstart” application I wanted AppFuse to be. It took me almost three months, but I finally released the first official version of AppFuse in April 2003.

过了几周以后,我认为struts-xdoclet这个名字很拗口,于是把项目改名为AppFuse。我为我的Struts章节生成了一个简单的应用并把它作为Struts Resume发布出去。在发布了Struts Resume以后,我刨除了其中和具体相关的东西使它重新成为一般的入门程序,正如我开始设想的那样。它花费了我几乎三个月的时间,但是最终我在20034月发布了AppFuse的第一个正式版本。

Since its initial release, AppFuse has gone through many changes and improvements. Most of the technology decisions were made from experience. It was a pain to keep my ValueObjects (VOs) and ActionForms in sync, so ActionsForms are generated using XDoclet. I found it tedious to write JDBC and more tedious to update SQL and VOs when adding new table columns. To solve this, I chose to use Hibernate for persistence and use Ant/XDoclet to dynamically create my database tables. Rather than lose my tables’ data each time, I integrated DBUnit, which also came in handy when running unit tests. I decided to use Tomcat/MySQL as the default server/database setup because I was most familiar with them. I integrated a plethora of unit/integration tests so I could make sweeping changes and verify that everything still worked (including the JSPs) by running ant test-all.

自从它的第一个发布版本以来,AppFuse已经经历了许多改变和发展。大多数的技术选择是凭经验得出的。保持ValueObjects (VOs)ActionForms同步是一件很痛苦的事情,于是我使用了XDoclet来生成ActionsForms。我发现编写jsbc代码是非常枯燥乏味的,而当更新表字段的时候修改sqlVOs的代码是一件更枯燥的事情。为了解决这些问题,我选择使用Hibernate作为数据持久层并且使用了Ant/XDoclet来动态创建我的数据库的表。Rather than lose my tables’ data each time,我集成了DBUnit, which also came in handy when running unit tests.使用Tomcat/MySQL作为默认的服务器和数据库是因为我最熟悉它们。我集成了所有的测试这样我能够在做出了大量改变以后运行ant test-all可以检查一切是否仍然可以正常工作(包括JSP

In March of 2004, I moved the AppFuse project from the Struts project on SourceForge to java.net. I had a couple of reasons for doing this. First of all, it was a sub-project on SourceForge, and its user base was growing quickly. It needed dedicated mailing lists and forums. Secondly, java.net seemed to do a better job of marketing projects and I’d heard their CVS system was much more stable. My experience at java.net has been quite nice: it’s a very stable system, and the administrators are very supportive of the project and have even helped with marketing it.

20044月,我将AppFuse项目从 SourceForgeStruts project移到了java.net。我这样作有几个原因。首先是AppFuseSourceForge的一个子项目,它的用户基础增长的非常快,需要专门的邮件列表和论坛。第二是因为java.net看起来提供了更好的销售项目的工作而且我听说他们的CVS系统非常的稳定。我在java.net的经历非常的美好:他是一个非常稳定的系统。而且管理员对项目的维护和支持非常的有效。

3          What is AppFuse?

AppFuse 是什么?

So after all that history, what is AppFuse? At its very core, AppFuse is a web application that you can package into a .war and deploy to a J2EE 1.3-compliant app server. It’s designed to help you create new web applications using a new target in its build.xml file. The new target allows you to specify a name for your project and a name for the database it will talk to. Once you’ve created a project, you can instantly create a MySQL database and deploy it to Tomcat using ant setup. Furthermore, you can verify that the basic functionality of your new application works by running ant test-all. At this point, you might sneer and say, “What’s the big deal? Anyone can create a .war file and deploy it to Tomcat.” I agree, but do you have a setup-tomcat target that will configure Tomcat with JNDI resources for connections pooling and mail services? Most of what AppFuse does is not rocket science. In reality, it’s nothing more than a directory structure, a build file, and a bunch of base classes — with a few features thrown in. However, it has vastly accelerated my ability to start projects and develop high-quality, well-tested web applications.

AppFuse究竟是什么?AppFuse是一个你可以打包位一个war文件并可以在兼容J2EE 1.3的应用服务器中运行的web应用程序。它被设计成能够利用build.xmlnew target帮助你建立新的的web应用程序。new target允许你指定你的项目名称和数据库名称。一旦你建立了一个项目后,你可以利用ant setup创建MySQL数据库并发布程序到Tomcat。而且你可以执行ant test-all测试新工程的基本功能。这时,你可能会嘲笑说,“这有什么的,任何人都可以创建一个.war文件并发布到tomcat”.我同意这点,但是你有setup-tomcat target可以用来配置Tomcat的连接池的JNDI资源和mail services?事实上,AppFuse并不是什么突破性的发明,它只是由一个目录结构,一个build文件,一堆基类等组成,然而,它能够让我能够快速构建可以高质量开发,易于测试的web应用程序。

AppFuse tries to make it as simple as possible to build, test, and deploy your application. It virtually eliminates setup and configuration, which are often the hard parts. Tools like Ant, JUnit, XDoclet, Hibernate, and Spring can be difficult to get started with. Furthermore, features like authentication, password hints, “remember me,” user registration, and user management are things that most web apps need. AppFuse ships with tutorials for developing DAOs, business delegates, Struts actions (or Spring controllers), integrating tiles and validation, and uses an Ant-based XDoclet task (written by Erik Hatcher) to generate master/detail JSPs from model objects. It uses slick open source tag libraries like Struts Menu (for navigation) and the Display Tag (for paging and sorting lists).

AppFuse试图尽可能简单的建造,测试,和发布你的程序。它实际上免去了安装和配置,这些往往是非常困难的部分。同时使用像Ant,JUnit,XDoclet,HibernatesSpring这样的工具是非常困难的。此外,还有一些像权限,密码提示,记住我”,用户注册和用户管理这些大多数web应用程序需要的部分往往是必须的。AppFuse还包括了开发DAOs, business delegates, Struts actions (or Spring controllers), 多层之间的通讯和验证,以及根据model objects 使用antXDoclet任务去生成一些JSP代码的指南。它还使用了很多优秀的开源标签库例如Struts Menu (用来导航) and the Display Tag (用来翻页和排序).

One of the best parts, in my opinion, is that it embraces the Java community’s ideas and suggestions. The directory structure and build file are largely based on Erik Hatcher and Steve Loughran’s excellent Java Development with Ant book. In this book, Erik built a sample application that inspired me to learn more about Ant and XDoclet — and use it in my Struts development.

在我看来,AppFuse最好的部分之一是集合了java社团的想法和建议。目录结构和build文件主要来自于Erik Hatcher Steve Loughran’的著作Java Development with Ant。在这本书里,Erik使用的一个示例程序给了我对于使用AntXDoclet的很多启示而且用在了我的Struts开发中。

When I first started learning and using Hibernate in AppFuse, I made many mistakes — and the community let me know. At first, I opened and closed its Session object for each DAO method. When Gavin told me this was a bad idea, I made modifications to use an OpenSessionInView pattern, with my own ServletFilter to do the work. I passed the session object into each method signature, for which the community repeatedly questioned my logic. My answer was, “I wanted to get it working more than anything — do you have a better idea?” The better idea turned out to be using the Session as a constructor argument, which worked pretty well.


Then, late last year, I discovered the Spring framework and found the beautiful solution I’d been looking for. Using its ORM support, I was able to eliminate any Session handling in AppFuse; now Spring elegantly handles it all. AppFuse now uses Spring’s OpenSessionInViewFilter. All I needed to do was configure it in web.xml and it manages opening and closing the session for me. When I integrated Spring in AppFuse’s persistence layer, I deleted two or three classes and reduced my LOC count by around 75 percent. All of the Hibernate issues I’d had before disappeared! In addition, I was quickly able to add a DAO implementation using iBATIS, which I worked with on a project last year. On that project, I discovered that iBATIS was easy to use and worked very well for interacting with complex database schemas.

在去年的晚些时候,我看到了Spring framework并且发现这是我正在一直寻找的优秀解决方案。使用他的ORM,我能够消除所有的Session操作在AppFuse中。Spring已经优雅的处理了他们。AppFuse 现在使用了 Spring OpenSessionInViewFilter。我所需要做的只是在web.xml中配置一下它就可以为我管理session的打开和关闭。当我集成了springAppFuse的数据持久层,我删除了两到三个class并且减少了大概百分之七十五的LOC数量。所有以前我使用的Hibernate 耦合都消失了,在我去年的一个项目上,我可以很方便的加入iBatisDAO实现。在这个项目上,我发现iBATIS非常容易使用并且在复杂的数据库结构上使用的非常好。

AppFuse is not only a jumpstart kit for your web apps; it’s also a showcase for integrating technologies like Hibernate, Spring, and Struts. Tutorials exist for integrating these different open source components, but rarely do they give you an application you can walk away with and use to develop your next application. In a sense, AppFuse is a glue that binds open source projects together. When I found Spring, it was a perfect fit, since it was the glue to configure components and loosely couple the different layers of an application. Erik’s book might have been the match that lit AppFuse, but Spring is the gasoline that really got it roaring. Spring has vastly simplified how I develop with AppFuse and forced me to follow best practices in J2EE. In short, it’s the best tool I’ve ever used with J2EE. I realize Spring is not the be-all-end-all for J2EE applications — AppFuse worked fine before I integrated it. However, it helped answer all of my “How should I do …” questions — which was a nice relief.

AppFuse不仅仅是一个web apps的框架搭建工具,它也是整合各种像Hibernate, Spring,Struts技术的展示柜。现在的一些指南能够告诉你如何整合这些不同的开源工具,但是很少能够提供一个你直接拿来就能用开发你的下一个项目的东西。在某种意义上,AppFuse是将开源技术绑定到一起的融合剂。当我发现了spring,它是非常的适合,因为它可以配置组件并且使得程序中不同的layer松耦合。Erik的书可能是点亮AppFuse的火柴,但是Spring就像汽油一样使得马达轰鸣起来。spring使我开发AppFuse非常的统一化并强迫我按照best practices in J2EE来做。简而言之,它是我在J2EE中使用过最好的工具。我认为到Spring不仅是所有J2EE程序所必须的――AppFuse在我整合它以前也跑的很好。但是它帮助回答了我所有”…..该怎么做?的问题这真是雪中送炭。

4          What Does the Future Hold?


AppFuse 1.5 was released at the end of May. Its major feature is the option to use Spring MVC instead of Struts. All of the tutorials have been updated to educate users how to use Spring (or Struts) for their web layers. For AppFuse 1.6, I plan to add support for using WebWork and SiteMesh, as well as make it easier to run unit tests from Eclipse and IDEA. By the end of the year, I hope to add Tapestry and JSF as MVC options. The middle tier and back end (Spring plus Hibernate) probably won’t change much. It’s a well-oiled machine at this point. This isn’t to say that I think AppFuse is perfect. I hope I continue to receive valuable feedback and suggestions. After all, this is the driving force behind improving its quality.

AppFuse 1.5 在五月底发布。它的主要特点是可以选择使用Spring MVC代替Struts。所有的指南都更新了,用来教会使用者如何在他们的web层使用Spring (或者 Struts)。对于AppFuse 1.6,我计划增加对WebWorkSiteMesh的支持,同样使它在EclipseIDEA中非常方便的运行单元测试。在今年年末,我希望能够增加TapestryJSF作为MVC的选择。中间层和后台(SpringHibernate)可能不会改变太大。It’s a well-oiled machine at this point.现在还不能说我已经认为AppFuse已经足够的完美了。我希望还能够获得有价值的反馈和建议。毕竟,能够不断的提高它是我的动力。

When I find innovative and easier ways to develop web apps, it ends up in AppFuse. People ask me why AppFuse doesn’t support Middlegen. The reason is simple: I’ve never used or needed Middlegen on a project, so I don’t see any reason to add it. If I end up on a project where I use Middlegen, you can bet I’ll end up adding support for it. Recently, I started using Spring’s MVC framework instead of Struts. At first, I found it a bit difficult to understand, so I implemented the web layer with Spring MVC. Since the web layer contains many features that I use in web apps (i.e., templating, validation, file upload, and exception handling), I learned the ins and outs of Spring MVC by integrating it.

当我发现能够革命性的非常简单去开发web应用时,就是AppFuse结束的时候。人们问我为什么AppFuse不支持Middlegen。原因很简单:我从来没有用过或者在一个项目中需要使用Middlegen,我也看不到任何原因需要加入它。如果我做完了一个使用Middlegen的项目,当然我会增加对它的支持。最近,我开始使用Spring MVC framework来替换Struts。一开始,我发现理解起来有些困难,我还是使用Spring MVC实现了web层。因为我在web层中使用了很多的特性(比如模板,验证,文件上传,异常捕获),所以在集成Spring MVC时学到了Spring MVC的很多细节。

Using and learning AppFuse is a good way to keep up to date with the latest releases of its dependent projects. I try to keep as up to date as possible with new releases — and due to AppFuse’s unit test coverage, I can easily test new releases by dropping them in and running ant test-all. This even works for dependent resources such as Tomcat and MySQL, in which I’ve found bugs via AppFuse. For me, it acts as a testing tool to verify the functionality of new open source releases.

使用和学习AppFuse是一个非常好的方法来跟上它所依赖的项目的最新发布版本。我试图尽可能的使用最新的releases,而且通过AppFuse的覆盖单元测试,我运行ant test-all能够很容易的测试最新的发布。它甚至能够工作在一些依赖的resourcesTomcatMySQL,我能够通过AppFuse发现一些bug。多我来说,它作为一个测试工具用来验证最新的的开源releases的功能。

5          AppFuse Light


Equinox is a lightweight version of AppFuse; hence its pseudonym “AppFuse Light.” I was inspired to create it when looking at the struts-blank and webapp-minimal applications that ship with Struts and Spring, respectively. These “starter” apps were not robust enough for me, and I wanted something like AppFuse, only simpler — with no build-time dependencies.

EquinoxAppFuse的简化版本;因此它的别名就是” AppFuse Light”.我从Struts struts-blankSpring webapp-minimal得到灵感来建立它。但是这些“starter”的程序对我来说是不够的,我想要一个更像AppFuse的东西,仅仅是简单几乎不需要花费时间去build

It’s designed to show web app developers how to start a bare-bones Struts/Spring/Hibernate app using the QuickStart Chapter in Spring Live. More functionality may be added in the future, but the main goal is to provide a better implementation of a bare-bones web app.

它被设计成用来展示给web开发人员如何去利用Spring LiveQuickStart章节去开始一个最本质的一个Struts/Spring/Hibernate应用。很多的功能可能会在未来被添加,但是最主要的目标是提供一个比较好的框架web程序。

Equinox should mostly be used for writing tutorials and rapid prototyping. I don’t recommend using it for starting a full-fledged production application. That’s what AppFuse is for.


6          How Do I Start Using It?


The best way to get started using AppFuse is to download it and read the QuickStart Guide. AppFuse is a part of the Java Enterprise Community on java.net. Its project homepage is at appfuse.dev.java.net.

最好的办法是下载AppFuse并且阅读QuickStart GuideAppFuseJava Enterprise Community的一部分。它的项目主页是appfuse.dev.java.net

If you’re interested in Equinox, you can read the QuickStart Chapter from Spring Live to build a quick and easy application using Struts, Spring, and Hibernate. If you like, you can view a demo of the MyUsers application that this chapter helps you build. Equinox is a sub-project of AppFuse on java.net. Its project homepage is at equinox.dev.java.net.

如果你对Equinox很有兴趣,你可以阅读Spring Live QuickStart 章节 来用Struts, SpringHibernate.快速建立一个简单的应用。如果你喜欢,你可以看view a demo of the MyUsers application,这一章会帮助你来建立应用。EquinoxAppFusejava.net上的一个子项目。它的项目主页是equinox.dev.java.net

7          Resources

Matt Raible is currently authoring Spring Live and is a member of the J2EE 1.5 Expert Group. He blogs about J2EE and his experiences on both jroller.com and raibledesigns.com.



  1. Rather than lose my tables’ data each time,我集成了DBUnit, which also came in handy when running unit tests.