实在是好事多磨,折腾了两个晚上才搞定了一个 HelloWorld Struts版,下面谈谈一点体会。
开发环境 Eclipse + MyEclipse (Struts 1.1)
Struts 1.1支持多模块开发,在myEclipse的Web Application Project里先建立新module (New->Struts 1.1 Module),
再依次加Form Action ActionForward (New -> Struts 1.1 Action, Form & JSP).有时myEclipse会找不到自己刚刚加的Form,手动添加即可,没什么大不了的。myEclipse的web.xml模板不符合标准,需要手动更改。TLD文件好像也不太对,可以用自己曾经做过项目的TLD代替。
下面是两个折腾我很久的问题。
1) 如果在我们security模块里有
<action
path="/UserSecurityCheck"
type="com.scs.presentation.security.UserSecurityCheckAction"
name="UserLoginForm" scope="request"
input="/init.do">
<forward name="loginSucceed" path="/mainmenu.jsp"/>
</action>
这个例子中,注意mainmenu.jsp前面有个/,ActionServlet会在当前module里寻找这个jsp,也就是说mainmenu.jsp需要放在/%webroot%/security/的目录下面,而不是直接在/%webroot%/下
2) struts的form标记定义了一个页面的表单,但该struts标记需要根据action的值来查找module config里的action mapping,并根据action mapping的值来初始化action form。因此,在form标记中需要获取一个module config。在这里,获取哪一个module config成为了form标记能否正常工作的关键,如果module config的获取值不正确,将会造成Cannot retrieve mapping for {action name}的错误。查找方法为首先从request中获取当前的module config,如果没有找到,就从servlet context中获取默认的module config。
现在struts framework的实现是这样的,只有ActionServlet正确地将module config对象赋值给request的属性Globals.MODULE_KEY后,后来的含form tag的属于该模块的jsp页面才能被struts framework正确与对应此module config挂钩。倘若编程人员/用户试图对某个模块发出的第一个请求是jsp而不是action,actionServlet就没有机会做上述的准备工作(因为web container会直接处理jsp请求,不会转发给actionServlet),那么接下来处理jsp中的form tag时,struts framework就会试图从default module config中寻找该actionMapping(因为request里的module specfic config依然为空,所以只好从default里找了),一般上这种寻找是没有结果的,最后framework就会返回Cannot retrieve mapping for ThisAction的错误。
结论是,接入每个module的第一个页面必须是由action请求(而不是jsp请求),以给actionServlet一个机会装载对应的module config并cache.
非常感谢下面两篇文章,它们帮助我解决了这个奇怪的问题,也间接导致了这篇文章的诞生。
http://202.100.72.44/news/itschool/pro/pro44134.htm
http://www.blogbus.com/blogbus/blog/diary.php?diaryid=139866
-=请提宝贵意见,并欢迎讨论,谢谢!=-