Model 2Struts 是基于 Model 2 之上的,而 Model 2 是经典的 MVC(模型-视图-控制器)模型的 Web 应用变体,这个改变主要是由于网络应用的特性 --HTTP 协议的无状态性引起的。Model 2 的目的和 MVC 一样,也是利用控制器来分离模型和视图,达到一种层间松散耦合的效果,提高系统灵活性、复用性和可维护性。在多数情况下,你可以将 Model 2 与 MVC 等同起来。
下图表示一个基于 Java 技术的典型网络应用,从中可以看出 Model 2 中的各个部分是如何对应于 Java 中各种现有技术的。
在利用 Model 2 之前,我们是把所有的表示逻辑和业务逻辑都集中在一起(比如大杂烩似的 JSP),有时也称这种应用模式为 Model 1,Model 1 的主要缺点就是紧耦合,复用性差以及维护成本高。
Struts 1.1 和 Model 2既然 Struts 1.1 是基于 Model 2 之上,那它的底层机制也就是 MVC,下面是 Struts 1.1 中的 MVC 实现示意图:
图解说明:其中不同颜色代表 MVC 的不同部分:红色(控制器)、紫色(模型)和绿色(视图)
首先,控制器(ActionServlet)进行初始化工作,读取配置文件(struts-config.xml),为不同的 Struts 模块初始化相应的 ModuleConfig 对象。比如配置文件中的 Action 映射定义都保存在 ActionConfig 集合中。相应地有 ControlConfig 集合、FormBeanConfig 集合、ForwardConfig 集合和 MessageResourcesConfig 集合等。
提示:模块是在 Struts 1.1 中新提出的概念,在稍后的内容中我们将详细介绍,你现在可以简单地把模块看作是一个子系统,它们共同组成整个应用,同时又各自独立。Struts 1.1 中所有的处理都是在特定模块环境中进行的。模块的提出主要是为了解决 Struts 1.0 中单配置文件的问题。
控制器接收 HTTP 请求,并从 ActionConfig 中找出对应于该请求的 Action 子类,如果没有对应的 Action,控制器直接将请求转发给 JSP 或者静态页面。否则控制器将请求分发至具体 Action 类进行处理。
在控制器调用具体 Action 的 execute 方法之前,ActionForm 对象将利用 HTTP 请求中的参数来填充自己(可选步骤,需要在配置文件中指定)。具体的 ActionForm 对象应该是 ActionForm 的子类对象,它其实就是一个 JavaBean。此外,还可以在 ActionForm 类中调用 validate 方法来检查请求参数的合法性,并且可以返回一个包含所有错误信息的 ActionErrors 对象。如果执行成功,ActionForm 自动将这些参数信息以 JavaBean(一般称之为 form bean)的方式保存在 Servlet Context 中,这样它们就可以被其它 Action 对象或者 JSP 调用。
Struts 将这些 ActionForm 的配置信息都放在 FormBeanConfig 集合中,通过它们 Struts 能够知道针对某个客户请求是否需要创建相应的 ActionForm 实例。
Action 很简单,一般只包含一个 execute 方法,它负责执行相应的业务逻辑,如果需要,它也进行相应的数据检查。执行完成之后,返回一个 ActionForward 对象,控制器通过该 ActionForward 对象来进行转发工作。我们主张将获取数据和执行业务逻辑的功能放到具体的 JavaBean 当中,而 Action 只负责完成与控制有关的功能。遵循该原则,所以在上图中我将 Action 对象归为控制器部分。
提示:其实在 Struts 1.1 中,ActionMapping 的作用完全可以由 ActionConfig 来替代,只不过由于它是公共 API 的一部分以及兼容性的问题得以保留。ActionMapping 通过继承 ActionConfig 来获得与其一致的功能,你可以等同地看待它们。同理,其它例如 ActionForward 与 ForwardConfig 的关系也是如此。
下图给出了客户端从发出请求到获得响应整个过程的图解说明。
下面我们就来详细地讨论一下其中的每个部分,在这之前,先来了解一下模块的概念。 |