ITEEDU

Struts Gossip: 模块化程序

Struts中很多设定都是在struts-config.xml中加以设定,在大型网站的开发中,有很多小团队会负责不同的模块,如果每一个团队都要对struts-config.xml进行设定,将会导致struts-config.xml的版本控制问题。

在Struts 1.1中,您可以为不同的模块分配不同的struts-config.xml设定档,方法是在ActionServlet的config参数后加上后缀字,例如将使用者登入的工作切分为login模块,则可以这么在web.xml中设定:
web.xml
...
<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/conf/struts-config.xml
</param-value>
</init-param>
<init-param>
<param-name>config/login</param-name>
<param-value>
/WEB-INF/conf/struts-config-login.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
...
onfig/login指定了login模块所使用的设定文件struts-config-login.xml,现在 login模块的开发人员只要专心于自己的开发与设定档,就如同之前的主题一般的设定,当ActionServlet收到请求时,它是根据模块前缀来了解 该使用哪一个模块,例如:
http://localhost:8080/strutsapp/login/admin.do
像上面的URL,我们称/strutsapp/login/admin.do是相对于domain的路径,而/login/admin.do是相对于应用程序context的路径,而admin.do是相对于login模块。

当ActionServlet接收请求,它判断URL中相对于context的前缀,例如上例中的login,于是得知该使用login模块,而在每个模 组的struts-config-xxx.xml中的设定则是相对于模块路径的,也就是说如果是struts-config- login.xml中的这样设定:
struts-config-login.xml
....
<action
path="/admin"
type="onlyfun.caterpillar.AdminLoginAction"
name="adminForm">
<forward
name="adminPage"
path="/WEB-INF/pages/admin/admin.jsp"/>
....
则所有的path设定会自动被加上login前缀,例如必须使用以下的路径才可以正确的请求到AdminLoginAction:
http://localhost:8080/strutsapp/login/admin.do
在模块中的 Action 在查找forward时,都是以所在的模块查找对应的struts-config-xxx.xml,例如上例的AdminLoginAction运行中查 找forward时,则会查找struts-config-login.xml中的forward,也就是说,模块中forward对象的查找预设都是相 对于模块路径,而不是相对于context路径。

那么如何从目前的模块转换到另一个模块?

当您的应用程序分作多个模块时,在使用者点选某个链接时,您有两个方法可以在模块之间切换,第一个方法是使用相对于context的路径来进行 forward 查找,您可以在当前的模块所使用的struts-config-xxx.xml中设定,例如在struts-config-login.xml中加入:
   ....
    <global-forwards> 
        <forward 
            name="switchModuleToSystem" 
            contextRelative="true" 
            path="/system/index.do" 
            redirect="true"/> 
    </global-forwards>
    ....
这是在全区可查找的forward中的设定,在<action>标签中也可以像上面一样使用<forward>标签,,例如:
    ....
    <action ... > 
        <forward 
            name="switchModuleToProfile" 
            contextRelative="true" 
            path="/profile/personalInfo.do" 
            redirect="true"/> 
    </action>
    ....
另一切换模块的方法就是使用SwitchAction,它需要在请求中带两个参数,一个是prefix,用来指定模块前缀名称,一个是page,用来指定相对于模块的资源路径,例如可以这么设定:
    ....
    <action-mappings> 
        <action 
            path="/switchModule" 
            type="org.apache.struts.actions.SwitchAction"/>
    </action-mappings>
    ....
之后可以使用这样的路径与参数来请求profile模块的personalInfo.do:
http://yourapp/switchModlue.do?prefix=/profile&page=/personalInfo.do