分享
 
 
 

深入Struts 1.1

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

王和全(ok_winnerboy@sina.com)

2003年 8 月

作为基于MVC模式的Web应用最经典框架,Struts已经正式推出了1.1版本,该版本在以往版本的基础上,提供了许多激动人心的新功能。本文就将带你走进Struts 1.1去深入地了解这些功能。

说明:希望本文的读者能有一定的Struts使用基础。

1、Model 2

Struts是基于Model 2之上的,而Model 2是经典的MVC(模型-视图-控制器)模型的Web应用变体,这个改变主要是由于网络应用的特性--HTTP协议的无状态性引起的。Model 2的目的和MVC一样,也是利用控制器来分离模型和视图,达到一种层间松散耦合的效果,提高系统灵活性、复用性和可维护性。在多数情况下,你可以将Model 2与MVC等同起来。

下图表示一个基于Java技术的典型网络应用,从中可以看出Model 2中的各个部分是如何对应于Java中各种现有技术的。

在利用Model 2之前,我们是把所有的表示逻辑和业务逻辑都集中在一起(比如大杂烩似的jsp),有时也称这种应用模式为Model 1,Model 1的主要缺点就是紧耦合,复用性差以及维护成本高。

2、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的关系也是如此。

下图给出了客户端从发出请求到获得响应整个过程的图解说明。

下面我们就来具体地讨论一下其中的每个部分,在这之前,先来了解一下模块的概念。

3、模块

我们知道,在Struts 1.0中,我们只能在web.xml中为ActionServlet指定一个配置文件,这对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过程中,可能会有些麻烦。因为许多开发人员都可能同时需要修改配置文件,但是配置文件只能同时被一个人修改,这样肯定会造成一定程度上的资源争夺,势必会影响开发效率和引起开发人员的抱怨。

在Struts 1.1中,为了解决这个并行开发的问题,提出了两种解决方案:

多个配置文件的支持

模块的支持

支持多个配置文件,是指你能够为ActionServlet同时指定多个xml配置文件,文件之间以逗号分隔,比如Struts提供的MailReader演示例子中就采用该种方法。

<!-- Action Servlet Configuration -->

<servlet>

<servlet-name>action</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

这种方法可以很好地解决修改冲突的问题,不同的开发人员可以在不同的配置文件中设置自己的Action、ActionForm等等(当然不是说每个开发人员都需要自己的配置文件,可以按照系统的功能模块进行划分)。但是,这里还是存在一个潜在的问题,就是可能不同的配置文件之间会产生冲突,因为在ActionServlet初始化的时候这几个文件最终还是需要合并到一起的。比如,在struts-config.xml中配置了一个名为sUCcess的<forward>,而在struts-config-registration.xml中也配置了一个同样的<forward>,那么执行起来就会产生冲突。

为了彻底解决这种冲突,Struts 1.1中引进了模块(Module)的概念。一个模块就是一个独立的子系统,你可以在其中进行任意所需的配置,同时又不必担心和其它的配置文件产生冲突。因为前面我们讲过,ActionServlet是将不同的模块信息保存在不同的ModuleConfig对象中的。要使用模块的功能,需要进行以下的预备工作:

1、为每个模块预备一个配置文件

2、配置web.xml文件,通知控制器

决定采用多个模块以后,你需要将这些信息告诉控制器,这需要在web.xml文件进行配置。下面是一个典型的多模块配置:

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

<init-param>

<param-name>config/customer</param-name>

<param-value>/WEB-INF/struts-config-customer.xml</param-value>

</init-param>

<init-param>

<param-name>config/order</param-name>

<param-value>/WEB-INF/struts-config-order.xml</param-value>

</init-param>

要配置多个模块,你需要在原有的一个<init-param>(在Struts 1.1中将其对应的模块称为缺省模块)的基础之上,增加模块对应的<init-param>。其中<param-name>表示为config/XXX的形式,其中XXX为对应的模块名,<param-value>中还是指定模块对应的配置文件。上面这个例子说明该应用有三个模块,分别是缺省模块、customer和order,它们分别对应不同的配置文件。

3、预备各个模块所需的ActionForm、Action和JSP等资源

但是要注重的是,模块的出现也同时带来了一个问题,即如何在不同模块间进行转发?有两种方法可以实现模块间的转发,一种就是在<forward>(全局或者本地)中定义,另外一种就是利用org.apache.struts.actions.SwitchAction。

下面就是一个全局的例子:

...

<struts-config>

...

<global-forwards>

<forward name="toModuleB"

contextRelative="true"

path="/moduleB/index.do"

redirect="true"/>

...

</global-forwards>

...

</struts-config>

可以看出,只需要在原有的path属性前加上模块名,同时将contextRelative属性置为true即可。此外,你也可以在<action>中定义一个类似的本地<forward>。

<action-mappings>

<!-- Action mapping for profile form -->

<action path="/login"

type="com.ncu.test.LoginAction"

name="loginForm"

scope="request"

input="tile.userLogin"

validate="true">

<forward name="success" contextRelative="true" path="/moduleA/login.do"/>

</action>

</action-mappings>

假如你已经处在其他模块,需要转回到缺省模块,那应该类似下面这样定义,即模块名为空。

<forward name="success" contextRelative="true" path="/login.do"/>

此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:

...

<action-mappings>

<action path="/toModule"

type="org.apache.struts.actions.SwitchAction"/>

...

</action-mappings>

...

4、ActionServlet

我们首先来了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet类来充当控制器。当然假如ActionServlet不能满足你的需求,你也可以通过继续它来实现自己的类。这可以在/WEB-INF/web.xml中来具体指定。

要把握ActionServlet,就必须了解它所扮演的角色。首先,ActionServlet表示MVC结构中的控制器部分,它需要完成控制器所需的前端控制及转发请求等职责。其次,ActionServlet被实现为一个专门处理HTTP请求的Servlet,它同时具有servlet的特点。在Struts 1.1中它主要完成以下功能:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有