1.1 回到过去!(Struts的简史)
当Java Servlet出现后,许多程序员很快意识到它是一个非常好的东西。它比标准的CGI更快更强大,而且简洁并能无限扩展。但是使用无尽的println()语句把HTML送到浏览器上真是又累有容易出问题,于是JSP出现了,JSP使得能在“外面”写Servlet。于是,程序员们能将Java代码和HTML简单的混合起来,而且具有Servlet的所有优点!The sky was the limit!
很快,Java网页应用成为了以JSP为中心的开发。这本身并不是一件坏事情,但是这对解决流程控制问题和其他一些网页应用特有的问题却帮助甚微。
于是,很清楚的,我们需要另一种模型了。
许多聪明的程序员意识到可以把JSP和Servlet结合到一起来发布网页应用。Servlet可以用来处理控制和流程的问题,JSP可以集中处理令人心烦的HTML。于是,把JSP和Servlet结合起来成为了大家都知道的Model 2(可能是因为单独使用JSP时称为Model 1)。
当然,这里并没有什么新的东西,并且JSP的Model 2很快就被指出是遵循从古老的Smarttalk MVC framework中抽象出来的传统的模型-视图-控制的设计方式。Java网页开发者现在趋向于认为Model 2和MVC的概念是互通的。在本手册中,我们使用MVC的范例去描述Struts的体系架构,这被命名为Model 2/MVC设计是最合适的了。
Struts项目最早是由Craig R. McClanahan于2000年五月发布的。它为Java社会提供了一个标准的MVC框架。在2001年七月,Struts 1.0发布,同时IOHO。Java Model 2的开发从来不会十分相似的。
1.2 MVC设计方式
在MVC设计方式中,应用程序的流程是被中心控制器调度的。控制器将请求(HTTP的请求)转到相应的处理去。处理是与模型结合的,每个处理都象一个请求和模型之间的适配器。模型代表了,或者说封装了应用程序的逻辑或者状态。控制器控制流程进行到相应的视图。控制一般通过查询一系列的对应(一般是从数据库或者配置文件中)来决定流程的。这在视图与模型之间提供了一种松散的联系,使得应用程序能非常容易的开发和维护。
1.2.1 模型:系统状态和系统逻辑的JavaBeans
基于MVC的模型通常可被划分为两个子系统--系统的内部状态和能改变此状态的行为。类比于语法,我们可以想象状态信息是名词,行为是动词。
许多应用程序使用一系列的JavaBean来代表系统的状态,这些bean的属性代表系统状态的详细信息。根据系统的复杂度,这些bean可以是自我包容的(即它们知道如何保持自己的状态),或者知道怎样从别的组件,例如数据库,搜索引擎,实体EJB,LDAP服务或者其他什么那里得到系统的状态。
大型应用通常将一系列可能的操作作为bean的方法,并调用他们来维护状态信息。例如一个购物车的bean,为每个当前的用户存储了会话信息,这些会话信息中包含了用户选中购买的东西的信息。这个bean应该有个checkOut()的方法,这个方法验证用户的信用卡,将用户的订单送到仓库以便包装和运输。还有一些系统将可能的操作分开表示,例如作为一个会话EJB。
另一方面,在小规模的应用中,操作将会被内嵌到Action类中,这些Action类是Struts控制层的一部分。当逻辑非常简单或者不需要逻辑在别的环境中重用时,是非常适合这样做的。
Struts框架体系对模型访问的支持是足够灵活的,但是我们强烈建议你将逻辑(怎样做)和Action类扮演的角色(做什么)分开来。
1.2.2 视图:JSP和表现组件
基于Struts应用的视图通常使用JSP技术。JSP页可以由被称为“模板”的静态HTML(或XML)加上动态内容组成。这些动态内容是基于对特殊的标记的翻译。JSP环境包含一系列的标准标记,例如<jsp:useBean>。除此之外,有J2EE提供了标准的方法去定义程序员自己的标记,这些自定义的标记被组织成为自定义标记库。Struts包含了一系列的自定义标记库可以用来建立多语言的用户界面,并且和ActionForm bean完美结合。ActionForm得到并校验系统需要的任何信息。
1.2.3 控制器:ActionServlet和ActionMapping
控制器接收用户的请求(通常来自浏览器),然后决定使用什么逻辑来处理,然后使用一个适合的视图来作出反应。在Struts中,控制器的主要部件是一个属于ActionServlet类的Servlet。这个Servlet通过定义一系列的ActionMapping来设置。一个ActionMapping定义了一个请求URI的路径并提供了一个Action类的完整名称。所有的Action都是org.apachestruts.action.Action的子类。Action封装了逻辑类的调用,结果的解释,并最终将程序控制交到一个合适的视图组件去,以对请求作出反应。
Struts在标准的ActionMapping类的基础上,也支持使用更多的属性去对框架进行操作。这使得你可以保存具体应用中的特殊信息并仍然使用Struts的其他功能。另外,Struts可以让你对逻辑定义“逻辑名称”,例如,一个Action的方法可以在不知道具体JSP位置的情况下,要求一个“主菜单”的内容。这些特征可以有效的帮助你将控制逻辑(做什么)和视图逻辑(怎样表示)分离开来。
1.3 Struts的流程控制
Struts框架提供了几个组件去实现MVC中的控制部分,他们包括:控制Servlet,开发者定义的请求处理,另外一些支持对象。
Struts的自定义标记库对MVC中的视图部分提供了直接的支持。他们其中的一些可以访问控制部分的对象,其他一些在开发的时候是非常好用的。其他标记,包括JSTL,也可以在Struts中使用。其他的表现技术,例如Velocity模板和XSLT也可以在Struts中使用。
MVC中的模型通常与具体的项目有关。Struts访问应用的具体事务很方便,但是将具体的编程交给了其他的技术,例如JDBC,EJB,Object Relational Bridge,或者Simpler等等。
让我们来看看所有这些是怎样结合在一起的。
当初始化的时候,控制器读取配置文件(struts-config.xml)并使用它去启动控制对象,这些对象形成了Struts的配置。Struts配置(和另外一些东西)定义了应用中使用的ActionMapping[org.apache.struts.action.ActionMappings]。
Struts的控制器Servlet查询ActionMapping,将HTTP请求转到其他组件去。请求可能被转到JSP或者开发者编写的Action[org.apache.struts.action.Action]的子类去。这些Mapping使控制器能将HTTP请求转到应用相关的Action去。
一个ActionMapping通常由以下一些属性:
一个请求路径(或者“URI”)执行这个请求的对象类型(Action的子类)其他需要的属性
Action的对象可以处理请求并向用户(通常是浏览器)作出反应,或者将控制转到其他地方去。例如,如果用户登录成功,login的action将会把请求转到主菜单的页面上去。
Action对象可以访问应用的控制器Servlet和它的方法。当将控制转移时,Action对象可以间接的将一个或多个共享的对象同时转移,包括JavaBean,这只要将他们放在一个Servlet共享的标准context中即可。
例如,Action对象可以建立一个购物车的bean,并增加商品到这个购物车中,然后将这个bean放到会话中,最后将控制转移到显示购物车里面的内容的JSP页面。因为每个用户都有自己的会话,所以他们都有自己的购物车。
在一个Struts应用中,绝大部分的逻辑可以使用JavaBean来编写。一个Action可以在不知道JavaBean怎样工作的情况下,调用JavaBean的属性。这就封装了逻辑,使得Action可以把精力集中在错误处理和流程控制上去。
JavaBean也可以用来管理输入的表单。网页应用的一个关键问题就是得到并校验用户的录入信息。使用Struts,你可以通过继承ActionForm定义自己的输入Bean类。ActionForm类使得存储和校验应用中的输入表单变得很容易。ActionForm的bean可以被自动的按照同一种标准和共享的上下文来存储,这样它就可以被其他对象,例如Action对象或者其他JSP访问。
Form bean可以被JSP用来收集用户录入的数据,一个Action对象来校验这些数据,然后再用JSP重现这个form的内容。在校验错误时,Struts使用一种共享的机制来抛出和显示错误信息。
Struts配置的另外一个元素是ActionFormBean。这是一个描述对象的集合,被用来在运行时建立ActionForm的实例。当一个mapping需要一个ActionForm时,servlet使用名字寻找这些描述对象并使用它去建立一个指定类型的ActionForm的实例。
这是使用ActionForm的请求的一个事件顺序:
控制器servlet得到或者建立ActionForm bean的实例控制器servlet将这个bean送到Action对象如果请求是提交数据,则Action对象校验数据。必要时,数据可以和一些信息被送回到录入表单并显示在页面上。否则,数据将会被传送到逻辑中去。如果请求是建立一个输入页面,Action对象则将输入页面需要的数据填入bean中。
Struts框架包括了可以自动填充JavaBean域的自定义标记。JSP需要知道的只是域的名字和将表单提交到哪里去。其他Struts标记能将Action或者ActionForm的信息自动的显示出来,这只需要与页面标记简单的结合。这些信息是多语言的并能根据用户所在的地区自动的选择合适的语言。
Struts框架和它的自定义标记库是在Java平台下结合起来支持多语言功能的。所有的域名称和信息可以从一个消息资源中得到。需要对其他语言进行支持,只需要简单的增加一个资源绑定即可。
除了多语言化,另外一个消息资源的好处就是保持了表单名字的一致性。并且可以在一个地方就能修改所有标签和信息文字。
对于最简单的应用,Action对象通常就包括了请求所需要的逻辑。然而,在很多情况下,Action对象应该调用另外一个对象(通常是JavaBean)去执行逻辑。这使得Action只集中处理错误和控制流程,而不用管具体的逻辑流程。为了能在另外的平台上重用,逻辑JavaBean不应该调用任何网页应用的对象。Action对象应该从HTTP请求中将需要的信息翻译出来并通过标准的Java变量传送到逻辑bean中去。
例如,对于一个数据库应用:
逻辑bean连接并查询数据库逻辑bean把结果返回到Action对象Action对象把结果存在请求的form bean中JSP在HTML中显示这些数据
无论是Action或者JSP都不需要知道这些数据是从哪里来的,它们只需要知道怎样包装和显示他们。
Struts用户手册翻译(1)
80酷酷网 80kuku.com