您的位置:首页 > 编程语言 > Java开发

Struts1.1多模块配置开发的问题

2006-08-10 13:58 357 查看
最近研究了一下struts1.1的多模块置开发,本以为已经基本掌握,但突然又遇到了问题。
在登录界面(默认模块)我试着调用一个logon模块的action,结果总是失败,找不到对应的配置,经过分析最后终于勉强成功。
现将有关东西记录一下:

web.xml配置文件
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>com.logon.MainServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/logon</param-name>
<param-value>/WEB-INF/struts-config-logon.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

struts-config-logon.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<data-sources />
<form-beans >
<form-bean name="logonForm" type="com.logon.LogonActionForm" />
</form-beans>

<global-exceptions />

<!-- ========== Global Forward Definitions ============================== -->
<global-forwards>
</global-forwards>

<action-mappings >
<action path="/logon" validate="false" scope="request" name="logonForm" input="/login.jsp" type="com.logon.LogonAction">
<forward name="logonSuccess" path="/logonDetail.jsp"></forward>
</action>
<action path="/logout" validate="false" scope="request" name="logonForm" type="com.logon.LogoutAction">
<forward name="logoutSuccess" path="/index.jsp" contextRelative="true"></forward>
</action>
</action-mappings>

</struts-config>

struts-config.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<data-sources />
<form-beans >
</form-beans>

<global-exceptions />

<!-- ========== Global Forward Definitions ============================== -->
<global-forwards>
</global-forwards>

<action-mappings >
</action-mappings>

</struts-config>

login.jsp位于webroot目录下:
<body>
<html:form action="/logon/logon.do" method="post" focus="ID">
<table border="0">
<tr>
<td>Login:</td>
<td><html:text property="ID" /></td>
</tr>
<tr>
<td>Password:</td>
<td><html:password property="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"><html:submit /></td>
</tr>
</table>
</html:form>
</body>

logonDetail.jsp位于webroot/logon/目录下:
<body>
<table border="0">
<tr>
<td>Login:</td>
<td><bean:write name="ID" /></td>
</tr>
<tr>
<td>Password:</td>
<td><bean:write name="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"></td>
</tr>
</table>
</body>

在这种情况下,访问login.jsp时出现错误:
javax.servlet.ServletException: Cannot retrieve mapping for action /logon/logon
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:825)
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:758)

......................................................................................

下面来看看html:form标签是怎样对action属性处理的:
/**
* Return the form action converted into a server-relative URL.
*/
public static String getActionMappingURL(String action, PageContext pageContext) {

HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
StringBuffer value = new StringBuffer(request.getContextPath());
ModuleConfig config =
(ModuleConfig) pageContext.getRequest().getAttribute(Globals.MODULE_KEY);
if (config != null) {
value.append(config.getPrefix());
}
.....................

return (value.toString());
}

此处的Globals.MODULE_KEY是ActionServlet处理request请求时,根据servletContext取得的prefix放进去的ModuleConfig。
所以,如果prefix为""的话(即struts默认的模块),只能从当前默认的ModuleConfig中查询action的路径,上面出现的错误正是这一情况。

这正是多模块之间的切换问题,怎么解决呢?

还没有想到更好的办法;

目前的想到的办法是不要使用html:form标签,不过这样的话,若切换到其它的模块,需要加上模块路径。
在form里的action上写上相对servlet的全路径(包括模块名):

<html:form action="/logon/logon.do" method="post" focus="ID">
更改为:<form action="logon/logon.do" method="post">

这样,当logon.jsp表单提交时,会切换到logon模块;

还有一种方法,在forward里设置contextRelative="true",在path属性里必须指明全路径:
如:<forward name="logoutSuccess" path="/moduleName/index.jsp" contextRelative="true"></forward>
无论当前在哪个模块,这样设置之后,当forward到logoutSuccess时,都会找到相对于servlet下的index.jsp。

无论哪种方法,虽然struts1.1支持多模块编程,但个人认为还不是很方便,当需要更改prefix的时候,不仅仅需要更改web配置文件或更改目录名,
如像这种情况,还需要更改jsp代码或者struts-config配置文件。

据说在struts1.2提供了更好的支持,有待研究。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: