Java实战之STRUTS第一章.doc_第1页
Java实战之STRUTS第一章.doc_第2页
Java实战之STRUTS第一章.doc_第3页
Java实战之STRUTS第一章.doc_第4页
Java实战之STRUTS第一章.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一部分 Struts 第一章 MVC与Struts介绍1.1 Model 2在Servlet/JSP规范的0.92版本中描述了Model 2。当时,Model 2定义了如何在同一个应用程序中联合使用servlet和JSP的体系结构。在后面的版本中,Model 2这个术语没有再出现过,但是在Web开发者中还是使用该术语。在Model2中,servlet处理数据存取以及控制流程,而JSP处理表现层。Model 2使得Java工程师和HTML开发者可以在同一个应用程序中都仅仅关注自己擅长的部分。对于一个符合Model 2要求的应用程序来说,其中一个部分的改变并不应当需要修改另外一个部分。HTML的开发者经常会改变页面的观感,但是这些修改并不影响后台servlet中的业务逻辑。Struts框架就是建立在Model 2体系结构上的。在Struts中有一个控制器servlet,它负责处理流程,还有一系列的辅助类来负责数据存取工作。Struts提供了很多标签库,使得Struts可以很容易地使用JSP页面。1.2 Struts概述不要吃惊,我们现在仅仅是简述一些Struts的基本知识。这仅仅是一次关于Struts的快速介绍。在我们试图深入到Struts框架结构的具体细节前,我们从它的整体框架入手。Struts使用Model 2体系结构。ActionServlet负责控制流程。另外一个Struts类:Action,负责存取业务逻辑类。当ActionServlet类从容器中获得一个请求时,它使用请求的URI(也称为路径)来决定是哪一个Action来处理该请求。一个Action可以检验输入的合法性、通过业务逻辑层来读取数据库或者其他数据服务中的信息。要检验输入的合法性或者是使用该输入来来数据库中的内容,Action需要用户提交给它处理数据。为了避免每一个Action都要处理从请求中提取输入数据的操作。Struts将这些输入数据绑定到JavaBean中。每一个这样的输入Bean都是Struts中ActionForm类的子类。ActionServlet通过查看请求的路径就可以决定哪一个ActionForm用来包含输入数据。这些ctionForm类都应该是org.apache.struts.action. ActionForm的子类。每一个HTTP请求都必须有一个HTTP响应。一般而言,truts自己并不生成响应,而是将请求转发到其他的资源上去例如JSP页面。Struts提供一个名为ActionFurward的类来将逻辑名保存到每个页面的路径。当业务逻辑部分已经执行完成后,Action会选择一个ActionForward,并且将它返回给总控servlet。总控servlet会使用在该ActionFurward中存储的物理路径来调用对应的页面来完成HTTP响应部分。Struts将所有这些方面的细节信息都定义在ActionMapping对象中。每一个ActionMapping对象都对应于一个指定的路径。当该路径被请求时,总控servlet会获取对应的ActionMapping对象。该对象会告诉总控servlet该使用哪些Action、ActionForm、ActionFurward对象。全部有关Action、ActionForm、ActionFurward以及ActionMapping的信息和其他的配置信息都在Struts-config.xml文件中声明。ActionServlet在启动的时候会读取该文件,并且创建包含所有这些配置对象的数据库。在运行时刻,Struts会使用这些对象,而不是文件本身。图说明了这些组件是如何集成在一起的。图 1-1 Struts 组件1.3 Struts体系结构现在,eb应用对于企业而言是非常重要的。如今,开发小组需要在有限的时间内构造出应用程序,但是,该应用程序也应当是正确的和可以长期运行的。Java开发者有许多工具来开发表现层页面,这些工具包括JavaServerPage和Velocity模板。我们同时还有和数据库打交道的工具例如和。但是,如何将这些部分组合在一起呢?我们已经有了足够的组件了还需要什么呢?1.3.1 历史的回顾在世纪年代后期,当图形用户界面刚刚出现时,软件架构师们发现应用程序可以被分成三个主要部分:处理数据的部分,生成屏幕图形和报表的部分以及处理用户和其他子系统之间交互的部分Ooram。在世纪年代初期,ObjectWorks/Smalltalk程序开发环境将这三层作为框架结构引入。在malltalk中,处理数据的部分被称为模式(odel),表现层被称为视图(View),交互层被称为控制(Controller)。许多现代的开发环境,包括Java的Swing都使用odel/View/Controler(MVC)体系结构(参看图12)作为自己体系结构的基础。图1-2 odel/View/Controler(MVC)体系结构基于Java的eb开发人员可以使用JDBC和JSP这样的工具来处理模式层和视图层,但是如何处理控制层呢?1.3.2 Struts介绍Struts的中心部分是MVC中的控制层。truts的控制层将模式层和视图层连接起来。该框架结构还包括一些其他功能,程序员可以利用这些功能来创建一个可伸缩的,足够酷的eb应用。truts被称为是“不可见的组件”的集合,它帮助程序员将那些原始的素材,例如数据库和eb页面组合成一个真正的实际应用系统。1.3.3 Struts控制层truts的控制层是一组可被编程的组件,程序员可以通过它们来定义自己的应用程序如何和用户打交道。这些组件可以通过逻辑名来隐藏那些很麻烦的,令人讨厌的细枝末节问题。开发人员可以通过配置文件来一次性地处理这些问题,然后就可以关注程序“干什么”而不是“如何干”。用户通过超链接或者HTML表来和eb应用进行交互。超链接可以将用户导向显示数据和其他元素的页面,例如文本和图像的页面。而表单则可以将用户数据提交给应用程序。正如图13所示,truts提供了可以用来定义超链接,表单和用户动作的组件。Hyperlinks/ActionForwardsHTML forms/ActionFormsCustom actions/Action classes图1-3 主要的Struts组件注意 Struts的组件是通过XML文件来进行配置。实际上,配置文件也是Struts框架结构的一个不可分割的组成部分。为了使得读者可以有一个全局的观念,我们将随着对每一个组件的介绍而介绍它们对应的XML元素。1超链接(Hyperlinks)对于应用程序开发者而言,超链接是指向应用程序的某些资源。这些资源可能是Web页面或者是一个客户动作。同时,它也可能包含一些指定的参数。在Struts中,开发人员可以将一个超链接定义为一个ActionForward对象。这些对象同时还具有一个逻辑名和“Path”的属性。这使得开发人员可以设置Path属性,然后通过名字在ActionForward中使用它们。ActionForward通常是定义在一个XML配置文件中,该文件是在Web应用启动时被Struts读取的。Struts使用这个XML定义文件来创建Struts的配置信息,其中就包含了一系列ActionForward对象。用来创建对应于起始页面的超链接的ActionForward对象的XML元素可能是如下定义:这个元素将会创建一个“name”属性的属性值为“welcome”,而“path”属性的属性值为“pagesindexjsp”的ActionForward对象。JSP页面和其他组件都可以使用“welcome”这个对象。Struts框架结构会找到逻辑名为“welcome”的ActionForward,并且根据其中的path属性来转跳到相应的页面。这使得开发人员可以改变链接的目标页面而不需要改变使用该链接的那些组件。在大多数的Web应用程序中,一般都是在JSP和Java代码中对于目的页面的地址进行硬编码,这样经常会导致程序难于修改以及潜在的错误。在Struts应用程序中,这样的细节配置都可以在不需要改变页面或者Java类文件的情况下,在整个应用程序中被改变。2HTML表单HTTP和HTML协议都提供了通过表单来提交数据的机制,但是如何处理这些数据就是程序员的事情了。Struts框架结构提供了AetionForm类,它可以处理一个HTML表单中的输入数据,校验输入数据的合法性,在需要时通过提供给用户对应的提示或者消息来纠正错误的输入。ActionForm具有一系列标准的方法来对数据进行校验和修改。Struts会自动地将JavaBean的属性和HTML表单的属性进行匹配。开发者定义ActionForm类,而Struts会自动处理其他的事情。下面的类会自动地从HTML表单的元素中提取具有“username”名字的域,并且将其值赋给自己的username属性。Public final class LogonForm extends ActionFormPrivate String username=null;Public String getUsername() return(thisusername); public void setUsername(String username) thisUsername=username;对于表单中的其他域,也可以增加相应的属性。这使得其他的组件可以通过一个标准的JavaBean来获取需要的值。从而避免每一个组件都要和HTTP请求打交道。ActionForm类是使用标准的Java类来创建的。Struts配置通过一系列的配置来查找ActionForm类。这些配置选项包括和。Struts框架结构使用是来定位和实例化AcfionForm对象。例如:Struts配置文件中包含了全部可用的ActionForm对象,其他组件只使用其对应的逻辑名就可以了。3.定制action参数一个HTML表单可以使用其action参数来通知浏览器向何处来提交数据。Struts框架结构也提供了相对应的Action对象来获取这个数据。框架结构会自动地创建、填充、校验并且将最后恰当的ActionForm对象传递给Action。Action对象然后就可以直接从ActionForm中提取数据。下面就是一个例子:public final class LogonAction extends Action public ActionForward perform(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)Throws IOException,ServletException MyForm myForm=(MyForm) form;/其他操作return mappingfindForward(“Continue”); Action最后将ActionForward对象返回给控制器。这使得Action可以通过例如continue或者cancel这样的逻辑名,而不是实际的系统路径名来定义目的页面。为了保证可控制性,控制层同时还会传递当前的HTTP请求和响应。实际上,一个Action对象可以做Java的Servlet能够做到的任何事情。除了ActionForward、ActionForm和Action对象外,Struts控制层提供好些其他组件,例如ActionMapping和ActionServlet对象。Struts还在控制层中就应用程序的本地化提供支持。 ActionMapping在一个Web应用程序中,每个资源都必须通过统一资源标识符(URl)来引用。这包括HTML页面,JSP页面和其他动作。为了给予custom Action一个URl或者路径,Struts框架结构提供了一个ActionMapping对象。类似于ActionForward或者ActionForm对象,该对象也是定义在一个XML格式的配置文件中。这使得同一个Action对象可以在不同的映射中被定义。例如,一个映射可能要求进行验证,而另外一个就可能不这么要求。 ActionServletStruts的ActionServlet在幕后安静地工作,它可以将其他的组件联合在一起。尽管它可以被子类化,大多数Strutsl0开发者将ActionServlet看成是一个黑盒:他们配置它然后就不管它了。我们会在第4章详细介绍Struts的配置。在Strutsl1中,ActionServlet就相对容易地控制了。 本地化Web应用程序通过提示和消息与用户进行交互。Struts组件中就内置了本地化的特性, 因此Struts应用程序可以被编写成一个国际化的程序。1.3.4 使用Struts开发Web应用程序为了使用Struts开发一个Web应用程序,开发者要把那些需要的超链接作为ActionForward对象,将那些HTML表单看作ActionForm对象,以及把那些客户定义的服务器端动作看作Action对象。那些需要存取EJB或者JDBC数据库的开发者可以用Action对象实现这些功能。这样使得表现层页面不需要和模式层打交道。Struts中的Action对象会收集视图需要的所有数据,然后转发给表现层页面。Struts提供了一个JSP标签库来简化编写HTML表单以及访问Action转发其他数据的工作。其他表现层的工具,例如Velocity模板也可以存取Struts框架结构,来生成动态Web页面。该过程如图1-5所示。JavaServer pageJSP标签Action对象图1-4将数据返回给视图层的过程 为显示进行 收集数据 数据格式化 在更深入地探讨Struts体系结构前,先让我们看看Web应用程序框架在设计时要面对的问题。1.4 为什么需要框架结构我们已经介绍了应用程序框架结构并且简单地讨论了框架结构的重要性。但是要真正地认识一个解决方案,你需要理解它解决的问题。开发一个Web应用是有其自身挑战的。因此要先了解那些开发Web应用面对的挑战。1.4.1 Web麻烦的源头Web开发者受到Web带来的两重限制:第一,我们希望客户端使用Web浏览器。其次,我们必须使用Web协议来通信。Web浏览器使用HTTP协议来通信,并且显示由HTML语言编写的页面。Web浏览器发送HTTP请求,而且处理接受到的HTML页面。对于那些不经常被改变的内容而言,这样的平台是很不错的。但是我们中的大多数人都需要编写动态的应用程序来给不同的用户提供定制化页面。尽管现在有一些有用的方法来编写动态效果,Web应用还是局限于HTTPHTML范围中。正如表1-1所示,Web协议和Web客户所带来的限制决定了如何编写Web应用。表1-1 Web应用面临的困难以及Web框架结构的解决方法限 制结 果HTTP协议在默认状态下,HTTP可以接受从网络上来的任何客户的连接请求HTTP主要用来传送简单的文本。传送二进制的数据要求使用复杂的扩展协议HTTP是无状态的,因此需要特别的方法来跟踪使用Web应用程序的用户HTTP是可信的,它期望客户端发回正确的信息客户端浏览器是处于Web应用程序控制之外的独立应用程序所有的浏览器都不是完全等价的,并且支持正式标志的不同子集通过浏览器的输入可能是不正确或者不完整的。有些输入甚至可能对应用程序进行攻击标准的Web格式语言HTML不能完全构造出桌面应用程序所能提供的界面元素应用程序通过默认数据来创建HTML控件可悲的是,这种情况并不会立刻改变。Web开发者不得不面对这些缺点,并且想办法来解决这些问题。正是因为编写一个具有鲁棒性的Web应用不得不面对这么多困难,因此使用框架结构来编写Web应用是至关重要的,它可以使你免于陷入无穷无尽的工作和麻烦中。在开发一个Web应用时,我们面对巨大的挑战。但是这些挑战也会带来巨大的收益。HTTP协议和HTML客户端使得Web应用程序可以被世界各地用户访问。从来没有其他的平台可以实现这一点。1.4.2 servlet解决方案Java的Servlet平台Sun,JST作为一个基本的平台来为基于Java的Web应用程序提供了很多重要的功能。Servlet类提供了基本的接口来处理HTTP的请求和响应。在HTTP协议的基础上,servlet提供了session的上下文,应用程序可以使用该上下文来跟踪用户。应用程序也可以使用servlet提供的其他上下文来将数据传递给浏览器或者应用程序中的其他servlet。Web应用程序还可以通过使用统一的方法来使用Java服务器提供的基本安全特性,而其他的HTTP服务器使用不同的方法来处理安全问题。总而言之,servlet规范描述了一个“容器”来管理servlet。该容器可能还提供了其他服务,例如对JSP的处理服务。servlet容器可以将其包括在自己的Web服务器中或者仅仅是将其作为现有的web服务器的一个插件。对于操作数据库,Java应用程序通过另外一个通用的框架结构:JDBC来进行处理。开发者使用标准的SQL语句并由插入的接口来处理那些和数据库打交道的细节。这使得在不改变源程序的情况下很容易改变后台数据库。对于那些使用后台远端数据库的高性能应用程序而言,开发者可以使用EJB平台。大多数的Java框架结构(包括Struts)在需要时候都可以使用EJB。一般而言,这些特性使得那些使用servlet技术的Web应用程序具有可移植性并简化了开发和维护工作。servlet和JSP已经提供了一个完全不同的方法来编写应用程序。类似于Struts这样的用Java语言实现的框架结构都是建立在servlet平台基础上的。它们主要是向程序员提供一个无缝的,简单的编程平台。1.4.3 Servlet框架结构如果不是全部的话,那么大多数Java语言编写的框架结构都使用Sun的Servlet平台作为基础。这些框架结构都捆绑了一个或者多个预先写好的servlet来供编程人员在自己的应用程序中使用。同时,它们还提供了一套类库,在自己的应用程序中,编程人员可以实现相应的接口或者继承其中的类来使用框架结构的功能或者实现自己的定制化。一般而言,Web应用程序的框架结构的主要目的是帮助你从浏览器中获取数据,同时将这些数据传递给自己的应用程序,这样应用程序就可以处理这些数据。最后,它们还负责将数据从应用程序的数据结构中取出传递给浏览器,使得用户可以通过浏览器看到结果。一些框架结构(例如TurbineASF,Turbine),同时还提供了辅助类和JDBC打交道。另外一些框架结构(例如Struts),是和模式层无关的。它们既不妨碍和数据库打交道也不提供辅助函数。但是还是有一些其他的框架结构(例如doFormsdbForms),专注于数据库的存取,而将其他的工作留给程序员来解决(或者是其他的框架结构,例如Struts)。框架结构的常用策略图 1-5 通常使用配置文件,控制器和表现系统的框架正如在图1-5中所示的那样,Java语言编写的Web框架结构都使用一些通用技术来保证产品更加容易设计、编写和维护。这些技术包括:外部配置文件。提供那些程序员不愿意在其源程序中包含的实现细节。中心控制器。作为一个通道来将HTYP请求放入更容易管理的队列中。该设计有时候被称为前沿控制器(Front Controller)G03。外部表现层系统。使得不同角色人员在编写应用程序的时候,可以在同一时刻并行工作。例如,Java程序员可以编写那些和中心控制器相关的类而页面设计师可以同时使用JSP编写页面。除了JSP以外,其他和表现层相关的系统,例如Volocity模板或者XSLT,都可以和Struts协调工作。框架结构一般都由多个组件组成,但是它们都具有上面这些特点。这些常用的策略在设计模式:可复用面向对象软件的基础Go4和J2EE核心模式Go3中是作为基本的程序范例进行说明的。许多程序员很乐于讨论和使用这些设计模式,但是还没有真正在Web环境中使用这些模式。使用这些已经被证明有效的设计模式例如MVC来构造应用程序可以更容易地保证自己的应用程序设计的正确性。在开发桌面应用程序时,使用这些设计模式带来的好处是显而易见的,但是如何在Web环境中使用这些模式还不为大多数程序员所了解。1.4.4 黑盒和白盒系列框架结构有些时候被分类为黑盒和白盒Fayad。“白盒”框架结构依赖于面向对象语言提供的继承和动态绑定特性。“黑盒”框架结构趋向于为可插入组件定义接口,并基于这些接口提供基本起步组件。这些接口和基本组件通常会提供热点(hotspot)方法,程序员可以直接使用或者重载这些热点方法来提供特别的行为。定义hotspot方法,也被称为变形(flexible)点或者是扩展(extension)点。这些方法处于那些可以被加入定制化代码的地方。热点(或者热点系统)描述了框架结构可以支持的应用程序的各种特性。本质上说,热点系统表现了框架结构能够解决的问题。大多数的具有面向对象特性的框架结构都是由一个核心子系统和一个热点子系统组成的。和其他框架结构一样,Struts也是混合使用白盒和黑盒技术。但是总而言之,框架结构应该更加倾向于黑盒。“黑盒”框架结构一般是更加依赖于设计模式。Struts当然也不例外。实际上,设计模式经常用来提供对框架结构的高层次描述Johnson。顺着这个思路,我们下面要介绍一下设计模式以及如何在Struts框架结构中使用这些设计模式。1.5 Struts、Model2和MVCStruts是这样说明自己:一个MVC(模式视图控制)设计模式的变异,基于Model2方法,封装了应用程序的特性结构。这样的说明可以使得一些Web设计人员很放心,但是对于另外一些不了解Model2或者MVC的人来说,却感到困惑。没有对MVC或者Model2的深入了解作为基础,的确是很难理解上面关于Struts的说明。1.5.1 MVC的演变我们说过ModelViewController原来是作为构造Smalltalk应用程序的框架结构。该框架结构支持三层结构的类:表现应用程序状态层、屏幕表现层和控制流层。这三层被称为模式(Model)、视图(View)和控制(Controller)。见图1-6。图 1-6 Smalltalk的MVC三层结构Smalltalk的MVC框架结构在著名的设计模式:可复用面向对象软件的基础(Design Patterns:Elements of Reusable Object-Oriented SoftwareCo4)中作为一个例子进行了研究。该书的四位主要作者逐渐被人称为“Gang of Four”。关于设计模式的更多细节问题。在设计模式一书中的MVC例子,着重说明了如何在其中使用通知/定购协议以及观察模式。当时的例子是对于同样的数据如何用不同的方法进行表现,例如使用饼图、条状图和电子表格。它是一个对应用程序进行模块化的极好例子,所以直到现在,也经常被使用。在图1-7的例子中,不同的视图可以在同一个时刻以不同的格式显示给不同的用户。应用程序一定要在后台数据(也被称为模式)改变时更新视图。为了更新数据,用户向控制器提交请求,而控制器会协调对数据据的改变。而视图必须同时进行更新来瓜数据的最新状态。图 1-7 模型数据可以被用于不同的视图中Smalltalk的MVC解决方案使用了“观察/通知”设计模式。在该模式中,每一个视图需要把自己注册为数据的观察者。而当数据改变时,每一个注册的观察者都会收到一个通知消息。将Smalltalk的MVC框架结构归纳成为Model-View-Controller体系结构,可以使用该体系结构在任何平台上构造应用程序。1.5.2 Model2的产生JSP的出现简化了动态页面的编写。JSP最初是作为servlet的替代品,同时也是微软ASP的竞争者。这样,程序员可以很轻易地创建具有servlet能力的服务器端页面。但是,更大的能力也意味着更大的责任。许多开发小组都发现,如果他们一不小心,则不同页面间的相互关联关系会带来的无穷维护工作,最后导致项目崩溃。那些高级特性都要求在页面中使用很复杂的嵌入脚本。但是这些嵌入脚本是很难被重用的除非将代码在不同页面间进行拷贝和粘贴。虽然页面中也可以包含辅助页面,但是这些辅助页面很难进行组织,也不容易在源代码树上进行组织。有时候甚至在源代码树中显得格格不入。许多程序员立刻意识到JSP和servlet应当联合使用来开发Web应用。servlet用来应付处理流;JSP应当专注于那些和输出HTML相关的繁琐工作。换句话说,使用JSP和servlet就被称为Model2(仅仅使用JSP就被称为Model1)。当然,对于Sun而言,这没有什么新鲜的。许多人迅速地指出Model2类似于经典的MVC体系结构。虽然有争论说使用Model2的应用程序仅仅是MVC构架,但并不支持“观察者通知”模式,但是在大多数情况下,Model2和MVC就是一个意思。不具有“通知”模式的MVC模式也有时候被称为MVC2或者Web MVC。1.5.3 应用程序层独立的视图层另外一个使得Model2不同于MVC的原因就是在Web环境下“观察者通知”模式并不合适。HTTP是一个“拉”的协议:客户端发出请求而服务器进行响应。如果没有请求,也不会有响应。而“观察者”模式则需要一个“推”协议来发出通知:服务器可以在数据改变时向客户端推出一个消息。尽管有模拟向Web客户端推数据的方法,但是它们并不符合Web应用程序的本质而且很难处理。图1-8描述了通常情况下MVC的例子:三个互相交互的组件构成了一个三角形。对于一个基于Web的应用程序而言,是很难维护该三角形的“改变通知”这一部分。对于那些全部资源在同一个服务器上并且客户端也保持着和服务器的连接的应用程序,这样的设计模式工作很好。但是对于那些资源是分布在好多服务器上,并且客户并不维护和服务器的连接的应用程序而言,这样的设计就不合适了。图 1-8 MVC 通常表示为3 个互相连接的组件包括基于Web的应用程序在内,许多分布式系统都不能够使视图对应用程序状态进行查询。因此更普遍的情况是分布式的应用程序进行分层设计Layers pattern POSA。简单而言,分层的思想就是将在同一层或者是临近层的类进行交互。在复杂系统中,这种设计可以保证臣系统的复杂性不会随着模块的增长而成指数增长。对于分布式应用程序而言,“分层”模式是设计中的核心模式。从MVC的上下文,在中心控制器以及改变通知上引入分层思想要对状态改变和状态查询责任。正如图1-10所示,分层的Web应用程序是使用平面设计而不是传统的MVC设计方式。控制层处于表现层(视图)和应用程序逻辑(模式)之间。表现层控制层应用程序逻辑数据库图1-19 Web应用层次后端资源 每一个模块的主要功能都没有改变。对于流程的一点改变就是状态查询以及改变通知都必须通过控制器。另外一个改变就是当视图(表现层)生成动态内容时,它使用由控制器提供的数据而不是直接由模式提供的数据。这个改变使得视图更加和模式无关,从而使得由控制器来选择数据并显示数据的视图。1.5.4 Struts如何实现Model2、MVC和分层Struts通过提供一个控制servlet来实现了Sun的Model2。该servlet可以被用来控制JSP页面和其他表现层设备之间的流程。通过使用ActionForward和ActionMapping来保证控制使用的逻辑名和表现层无关。Struts实现了MVC和分层模式。JSP页面可以用逻辑名进行引用。而控制器组件在运行时刻提供实际的URL。表1-2显示了Struts的核心类和经典MVC模式中的功能的对应关系。表1-2 核心Struts类以及MVC的关系类描 述ActionForward用户指示器或者视图选择器ActionForm要求改变状态的数据ActionMapping要求改变状态的事件ActionServlet控制器的一部分,负责接受用户指示以及状态改变,还负责选择下个视图进行显示Action classes控制器的一部分,负责和模式打交道。通过模式改变状态数据,同时告知ActionServlet选择哪一个视图显示除了这些核心类以外,Struts使用很多的配置文件和视图辅助函数来解决控制器和模式之向的差距。表1-3显示了Struts配置文件和它们在体系结构中相应的功能描述。表1-3 Struts配置文件文 件目 的ApplicationRpertiesStruts-config.xml存储本地化的消息和标签,应用程序可以通过使用它们实现国际化。 存储控制器对象的默认配置信息。包括模式支持的用户指示、状态改变和状态查询为了将数据从Struts配置文件中表现在视图中,Struts框架结构提供了一系列的辅助函数作为JSP的标签使用,我们在表1-4中列出它们。表1-4 Struts视图帮助函数标签库描述符目 的Struts-html.tldStruts-bean.tldStruts-logic.tld对于HTML表进行扩展的JSP标签对于JavaBean进行扩展的JSP标签对于属性值进行测试的JSP标签将这些合在一起考虑,表1-5分层说明了Struts操作。表1-5 分层说明的Struts组件视 图 层控制层模式层JSP标签控制JSP页面,Velocity模板以及由开发者提供的其他表现方法ActionForwardActionForm类ActionMappingActionServietAction类ActionErrorsMessageResources各种各样的辅助函数,例如Commons-Digester和Commons-BeanUtilsGenericDataSource开发者提供的其他数据服务和API要注意的是,根据分层模式的定义,每一个模块都仅仅可以和与它同层或者相邻层的模块进行交互。也就是说,处于模式层的模块不可以直接和视图层的模块打交道。实际上,控制器和视图通过servlet平台提供的request对象、session对象和应用程序上下文进行交互。为了创建一个和JDBC数据库的连接,控制器和模式通过文件和内存(在加载XML文件和属性文件的情况下)或者其他服务(例如TCP)进行交互。1.6 Struts控制流因为Web应用程序是动态的,因此很难用“全能的控制流”来控制。根据环境的不同,不同的事情可能以不同的方式发生(特别是Web应用程序)。但是它们还是有一个大致的顺序。如果你是Struts的,或者是应用程序框架结构的,甚至是Web应用程序的新手,该流程可能第一次很难看清楚,因此也就不容易看出Struts在尽力解决的问题。在本书中,我们会详细地解说这些问题。但是,此时我们在介绍每一个细节前,先看看整个流程的概况。当你阅读本书时,我们建议你经常回来看看本节,从而了解每一个细节问题是如何组成整个框架结构的。1.6.1 流程概述图1-10通过可视的序列方式说明了Struts的请求响应处理流程。让我们顺着该流程走一遍。在括号中的数字就是指代图1-10中的动作。图1-10 Struts的请求响应处理流程(UML图由Jean-Michel Garnier)客户请求和Action对应的URl模式匹配的地址(1)。容器将该请求传递给ActionServlet。如果该应用程序是一个模式化应用程序,则ActionServlet选择恰当的模块。ActionServlet查看该路径对应的值。如果该路径对应的值指向一个form bean,则ActionServlet检查是否已经创建一个bean。如果已经存在一个bean,则ActionServlet重置该bean,并且用HTTP请求中的数据来填充该bean。如果该路径对应的值已经将validate属性设置为真,则调用form bean对应的validate方法。如果validate方法失败,则servlet将控制转向input属性指定的路径,控制流结束。如果该值指定了一个Action类型,如果该Action已经存在,则重用它。否则就重新创建一个。该Action对应的perform或者execute方法被调用,同时会被传递给实例化的from bean(或者空对象)。Action对象可能会生成form bean,调用具有业务逻辑的对象以及做任何其他需要做的事情。Action返回一个ActionForward对象给ActionServlet。如果ActionForward对象是另外一个Action对应的URI,则我们从头开始一次。否则,显示页面和其他资源。在大多数情况下,是显示JSP页面。在使用Jasper或者其他等价物(而不是Struts)时,生成页面(2.3)。如果JSP页面使用了Struts提供的HTML标签,并且这些标签在HTTP请求中发现了合适的ActionForm,则它们从ActionForm中的数据来生成自己的控制。否则,标签创建一个对应的ActionForm。从Struts11开始,如果ActionForm自己要创建一个对象,则该标签同时也会调用ActionForm的reset方法。如果你仅仅需要创建一个空白的form(11),则你可以使用一个标准的ForwardAction并且通过Action传递给控制器,然后再传送给页面。1.6.2 更微小的细节真正可怕的是细节问题。上一节中的大纲和图表很好地概述了全局的流程,但是也省略了一些重要的细节。让我们更深入地挖掘,并说明更加底层的细节。正是因为我们使用HTTP协议,因此所有的事情都要从HTTP请求开始。1容器收到HTTP请求Struts框架结构的关键组件是ActionServlet。和其他servlet一样,它在类似于Tomcat、Resin或者WebLogic的容器中运行。当这些容器启动时,它读取配置文件(webxml)。该文件告诉容器装载哪些servlet。标准的servlet设置是sevlet mapping。容器使用这些配置信息来决定哪些请求会被发送给该servlet。actiondo*这个配置使得容器使用ActionServlet来处理任何符合模式/do/*的请求。这包括/do/This,或者/do/That和/do/something/Whatever。许多应用程序愿意使用后缀的方式进行映射:action*do该模式同样和thisdo,或者thatdo或者somethingwhateverdo进行匹配。任何有效的扩展或者前缀都可以使用。而do仅仅是最常用的选择。当请求对应的路径匹配servlet指定的上下文时,容器会将该请求发送给我们的ActionServlet。而不匹配我们模式的请求就不会发送给ActionServlet。例如,一个匹配jsp的请求会被发送给容器处理JSP的服务(对于Tomcat或者WebSphere而言就是Jasper)。在你的应用程序中也许还有其他的servlet,它们会处理其他模式。而并不匹配任何模式的请求会被发送给容器对应的默认web服务器。2ActionServlet收到请求当我们的ActionServlet收到请求时,它进行一系列的处理来定位、映射、生成bean和最终处理action。其中的某些步骤仅仅适用于Struts11应用程序。处理多部分请求。如果该请求具有多部分(一个具有MIME附件的表),则servlet会使用一个特别的处理器来包装该请求,从而可以避免在后面的处理中出错。处理path标志。ActionServlet检查该路径是不是对应应用程序的模块,如果是,则选择合适的模块配置信息struts11。处理locale标志。默认的,ActionServlet会检查用户在session中是否存在标准的local对象。如果不存在local对象,则ActionServlet将会创建一个并且将其放人用户的session中。该对象会被用来对表现层进行本地化操作。处理content和NoCache标志。默认的MIME类型和可选的请求头被加入到响应中。处理Mapping。AetionServlet检查ActionMappings,将要处理的路径映射到对应的Action对象。如果没有对应的Action对象,则ActionServlet会将请求转发给默认的(或者是未知的)Action(如果设定了该Action),或者生成“不正确请求”的错误返回。如果找到对应的Action,则将Action放入请求中来进行进一步的处理。处理Roles标志。AetionServlet检查用户是否有权限来访问该action。Struts11处理ActionForm。AetionServlet检查是否指定了一个ActionForm。如果指定了ActionForm,则servlet会检查在指定的范围内是否存在一个ActionForm(默认的范围是session)。如果不存在ActionForm,则ActionServlet会创建一个。进行数据填充。ActionForm的reset方法会被调用,然后通过反射机制对其进行自动填充。那些符合ActionForm属性的参数会被填充到ActionForm中去。其他的参数和属性则被忽略掉。合法性校验。ActionForm的validate方法被调用。如果该方法返回false,则控制会被转移到在ActionMapping中input属性指定的值上,同时Action也不会被处理。处理Forward或者Include。如果ActionMapping指定了forward或者include属性,控制就会被转移给另外的资源。否则,ActionServlet将请求给Action对象处理。处理Action。如果ActionMapping指定了Action类型,则ActionServlet会检查是否已经实例化了一个该类。如果没有找到实例化的类,则会创建一个Action对象。对于每一个Action类而言,仅仅存在一个实例(Singleton模式)。该实例会通过多线程来处理全部的请求。Servlet会调用该Action类的perform或者execute方法,同时会将相应的请求、响应、ActionMapping以及任意的formbean传递进去。Action可以进行任意需要的操作,这些操作包括:访问数据系统,例如JDBC数据库。在HTTP请求中创建要被视图使用的对象。如果需要,在用户的session中创建对象。如果需要,修改用户session中的对象,例如用户的locale。执行应用程序需要的任意其他业务逻辑。处理异常或者任意其他的错误情况。直接发送HTTP响应,或者(也是更常见)返回一个ActionForward对象给servlet。其中某些动作,例如访问数据库,经常是由Action调用的业务对象进行处理(业务代理模式)。Action是用来处理那些和Web相关的任务,但是任何和业务逻辑相关的代码都应该放到业务对象中去。Action是控制器对象,因此应当用来处理应用程序的核心业务逻辑。3.Action返回ActionForward当Action完成其工作后,它返回一个ActionForward对象。如果ActionForward为空,则ActionServlet就假定响应已经生成了而不会做进一步的处理。否则,ActionServlet会读取ActionForward对象,然后将HTTP请求进行重定向或者转发给恰当的资源。4.Jasper(或者等价者)生成JSP页面当ActionServlet将请求发送给JSP时,该请求会被另外一个服务例如Jasper,进行处理。典型地,程序员使用Struts或者其他标签库来生成页面中的动态部分。有些时候,也使用JSP模板来使用其他模块构造页面。更普遍的方法是将要传递给页面的动态内容保存在请求对象上下文的某个JavaBean中。这也被称为视图辅助模

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论