
图1 Struts体系结构
Struts是Apache组织中开源项目之一,主要用于实现Web项目中表示层。Struts的核心是ActionSevlet,ActionServlet是一个通用的控制组件,承担MVC中Controller的角色,其核心是Struts-config.xml。在Struts中,用户的请求一般以*.do作为请求服务名,所有的*.do请求均被指向ActionSevlet,ActionSevlet根据Struts-config.xml中的配置信息,将用户请求封装成一个指定名称的FormBean,并将此FormBean传至指定名称的ActionBean,由ActionBean完成相应的业务操作,如文件操作,数据库操作等。每一个*.do均有对应的FormBean名称和ActionBean名称,这些在Struts-config.xml中配置。
2.2.2 Hibernate简介
Hibernate是一种新的ORM映射工具,它不仅提供了从Java类到数据表之间的映射,也提供了数据查询和恢复机制。相对于使用JDBC和SQL来手工操作数据库,使用Hibernate,可以大大减少操作数据库的工作量。
Hibernate可以和多种Web服务器或者应用服务器良好集成,如今已经支持几乎所有的流行的数据库服务器(达16种)。图2显示了Hibernate如何使用数据库和配置文件数据库来为应用程序提供持久服务和持久化对象。
Hibernate的接口大致可以分为以下几种类型:
●一些被用户的应用程序调用的,用来完成基本的创建、读取、更新、删除操作以及查询操作的接口。这些接口是Hibernate实现用户程序的商业逻辑的主要接口,它们包括Session、Transaction和Query。
●Hibernate用来读取诸如映射表这类配置文件的接口,典型的代表有Configuration类。
●回调(Callback)接口。它允许应用程序能对一些事件的发生作出相应的操作,例如Interceptor、Lifecycle和Validatable都是这一类接口。
●一些可以用来扩展Hibernate的映射机制的接口,例如UserType、CompositeUserType和IdentifierGenerator。这些接口可由用户程序来实现(如果有必要)。

图2 Hibernate体系结构
Hibernate使用了J2EE架构中JDBC、JTA、JNDI等技术。其中JDBC是一个支持关系数据库操作的一个基础层;它与JNDI和JTA一起结合,使得Hibernate可以方便地集成到J2EE应用服务器中去。
三、Ruby on Rails与Struts+Hibernate之比较分析
Ruby on Rails堆栈与轻量级J2EE 架构Struts+Hibernate堆栈之间的基本区别很小,两者都有用来执行应用程序代码的容器,都有帮助分离应用程序的模型、视图和控件的MVC框架,以及持久存储数据的机制。图3是对两种架构堆栈的比较。
3.1前端控制器
Ruby on Rails的DispatchServlet和Struts的ActionServlet都是前端控制器模式的例子,它们提供了相同的功能。它们接受HTTP请求并解析URL,把请求的处理转发给适当的动作。在Rails中,动作是扩展自ActionController的类;Struts中,动作是扩展自Action的类。两个前端控制器之间的主要区别是它们如何决定处理具体请求的动作。

图3 Ruby on Rails与Struts+Hibernate堆栈的比较
Rails根据请求的URL发现适当的动作。图4显示,URL http://localhost/order/delete/4告诉Rails调用OrderController实例上的delete方法,并将4作为可用的实例变量。Rails知道/order将映射到文件order_controller.rb中定义的一个控制器类。如果在控制器中定义了find方法,那么只要用find替代URL中的delete,就可以调用这个方法。

图4 Rails和Struts中的URL映射
Struts采用了不同的方式,开发人员需要把特定请求的映射外部化到XML配置文件中的Action类。当首次装入ActionServlet时,它将解析这个文件,并准备接受请求。根据约定,以.do结束的请求被重定向到ActionServlet,由ActionServlet分派到适当的Action。图4的XML是一个典型的映射,它告诉ActionServlet把叫作deleteOrder.do的请求转发到controllers.order.DeleteOrderAction作进一步处理。
3.2动作和模型
在Rails和Struts中,动作用来充当前端控制器和模型之间的桥梁。开发人员提供动作的现实,从而提供特定于应用程序的请求处理。前端控制器负责接受请求,并把请求传递到特定动作。图5显示了Rails和Struts基本的动作层次结构。
在Rails中,必须扩展ActionController::Base,让模型参与到请求处理中。Rails没有将ActionController的实例池化;相反,它为每个请求创建新的实例。虽然这对性能可能有负面影响,但是它可以让开发变得更容易。开发人员不需要关注Struts中存在的线程问题,因此,会话、请求、标题和参数都可以作为ActionController的实例成员来进行访问。
Struts要求开发人员扩展Action并覆盖execute(),以处理请求。通常,每个Action类都提供了非常具体的工作单元。图5显示了三个特定动作:SaveOrderAction、DeleteOrderAction和ListOrdersAction。前端控制器将调用execute()方法,传递给它许多有用的对象,其中包括HTTP请求和响应对象。ActionForm是一个类,可以方便地向视图来回传输并验证与表单有关的输入,ActionMapping包含映射的配置信息,就像图4的XML所描述的那样。execute()方法返回ActionForward对象,Struts用这个对象来确定对请求继续进行处理的组件。

图5 Rails和Struts的动作层次结构
3.3持久性框架
持久性框架用于在应用程序层和数据库之间交换数据。Rails和Hibernate的持久性框架都可以归类为对象/关系映射(ORM)工具,它们接受数据的对象视图,并将该视图映射到关系数据库内的表中。使用两种框架的目的都是为了减少与关系数据库有关的开发时间。但是,图6显示了两者在设计和配置上的一些区别。

图6 ActiveRecord和Hibernate持久性框架的比较
Rails 的 ORM 框架叫作 Active Record,它基于同名的设计模式。Active Record 是包装数据库表或视图中数据行的对象,封装数据库访问,在数据上添加域逻辑。在 Rails 中,每个域对象都将扩展提供 CRUD 操作的 ActiveRecord::Base。Active Record 不需要映射文件;实际上,使用 Active Record 的开发人员不需要对 getter 或 setter、甚至类的属性进行编码。通过一些漂亮的词汇分析,Active Record 能够判断出,Order 类将映射到数据库中的 ORDERS 表。使用 Ruby 反射和元编程的组合,表的列可以变成对象的属性。访问器和调整器也添加了进来。

图7 order.rb
图7显示了 Order 类的完成后的代码。在 Order 类体中有一行代码定义了它与 Item 对象的关系。has_many 是一个静态方法调用,符号 :items 是它的参数。ActiveRecord 用 :items 发现 Item 域对象,然后将这个 Item 对象映射回数据库中的 ITEMS 表。
Hibernate基于DataMapper模式,在这种模式中,特定的映射器类Session负责在数据库中持久存储和检索数据。Hibernate可以持久存储任何Java对象,只要这个对象符合JavaBean规范。XML映射文件描述了如何将类映射到数据库中具体的表,并描述了类与其他类的关系。
图8显示了Hibernate映射文件的一个实例。class标签把Order对象映射到ORDERS表,还有许多子标签用于描述其属性、ID订单名称,以及同models.Item的一对多关系。

图8 Order.hbm.xml
四、结束语
Ruby on Rails提供了开发Web 应用程序的一种极其快捷的途径,正在和已经引起业界相当的兴趣。它更倾向于清楚的代码而不是配置文件,而Ruby语言的动态性质在运行时生成了大部分管道代码。大多数Rails框架都是作为独立项目创建的,而且应用程序开发能够从一组同类组件受益。相比之下,典型的J2EE架构倾向于构建在通常独立开发的最好的组件之上,一般使用XML进行配置并将组件组合在一起。
参考文献:
[1]吴吉义.基于Struts+Hibernate+Spring的电子政务应用系统架构[J].电子政务,2005,(12):32-38.
[2]Rod Johnson.EXPERT ONE-ON-ONE J2EE DEVELOPMENT WITHOUT EJB[M].北京:电子工业出版社,2005.
[3]DAVE THOMAS, CHAD FOWLER, ANDY HUNT.PROGRAMMING RUBY: THE PRAGMATIC PROGRAMMERS' GUIDE[M].北京:电子工业出版社,2006.
[4]JAMES TURNER,KEVIN BEDELL.STRUTS KICK START[M].北京:电子工业出版社,2004.
[5]Aaron Rustad.Ruby on Rails and J2EE: Is there room for both?[EB/OL].
http://www-128.ibm.com/developerworks/web/library/wa-rubyonrails/, 2006-06-01/2006-07-15.
[6]David Mertz.Fast-track your Web apps with Ruby on Rails[EB/OL].
http://www-128.ibm.com/developerworks/linux/library/l-rubyrails/, 2006-06-01/2006-07-15.
凡《网络安全与数据治理》(原《信息技术与网络安全》)录用的文章,如作者没有关于汇编权、翻译权、印刷权及电子版的复制权、信息网络传播权与发行权等版权的特殊声明,即视作该文章署名作者同意将该文章的汇编权、翻译权、印刷权及电子版的复制权、信息网络传播权与发行权授予本刊,本刊有权授权本刊合作数据库、合作媒体等合作伙伴使用。同时,本刊支付的稿酬已包含上述使用的费用,特此声明。