Cannot retrieve mapping for action:

struts的form标记定义了一个页面的表单,但该struts标记需要根据 action的值来查找module config里的action mapping,并根据action mapping的值来初始化action form。因此,在form标记中需要获取一个module config。在这里,获取哪一个module config成为了form标记能否正常工作的关键,如果module config的获取值不正确,将会造成对应的action mapping找不到或者找到但却不是正确的action mapping。从而造成Cannot retrieve mapping for {action name}的错误或者其他意外错误。在form 标记的lookup方法中,包含了该查找module的过程,它的查找方法为首先从request中获取当前的module config,如果没有找到,就从servlet context中获取默认的module config(即module prefix为""的module)。

我们分析ActionServlet的初始化方式,可以发现ActionServlet将初 始化好的module config分别保存在servlet context的属性中,其中的属性名为Globals.MODULE_KEY+prefix,但request对象的当前module config是怎么来的呢。它是ActionServlet 在获取到一个请求后,根据请求的url与保存在servlet context里的module prefix进行匹配,如果匹配成功,则将属性名为Globals.MODULE_KEY+"匹配成功的prefix"的module config作为当前的module config返回,该过程出现在ActionServlet的process方法中,在select module的时候,将根据以上规则,选择当前的module config,并保存在request的属性Globals.MODULE_KEY。并将实例转给RequestProcessor对象。

我们从上面的分析中可以看出,包含form tag的jsp页面,如果要正确的将自已关联到一个module中,则需要事先将当前module config对象放在request请求中,但存放module config到request请求的动作是在ActionServlet中完成的。因此,页面只有在经过了对一个Acton进行处理后(在处理 action的过程中,会根据action的url 来匹配当前的module,并将其保存在request中),并通过redirect=false的方式下重定向到一个jsp页面,才能使该jsp页面正 确的关联到module中,否则都将关联到默认的module config中,如直接在地址栏中键入jsp的url这种情况下,所有的jsp文件都关联到默认的module config中。

from:http://www.blogbus.com/blogbus/blog/diary.php?diaryid=139866

今天试着把写的系统登录模块加到我们现有的模块里来,他写的时候因为有些试验的成分,所以没 有按照我们项目的配置来写,也没有按照我们的模块来划分配置,加过来以后重新配置了模块信息,结果居然无法正常运行。显示错误:“cannot retrieve action mapping  。废了九牛二虎之力,都无法解决。web.xml、struts-config、模块配置,一切看起来都无比的正常,但就是运行不了。真搞不清楚是哪里出 了问题。还以为搞不定,晚上要加班了,谁知道,踏破铁鞋无觅处,柳暗花明又一村,在google上搜索关键字"action mapping 找不到",第一个链接居然就是问题的答案!(还从来没有只点一次就可以找到问题答案的经验,所以兴奋无比^O^)

        总的来说,问题的原因就在于,struts是在第一次收到对action的请求(注意:不包括jsp的请求)时,提取这个请求的url的路径信息,把相应 模块的mapping信息设置到请求中去。如果在进入一个模块时,第一次访问的是一个jsp页面,而在这个jsp页面中提交到该模块的一个action, 就会出现找不到action mapping的情况。这就是因为,在进到这个模块时,访问的是jsp,这个模块的任何一个action都没有被访问到,所以struts的 ActionServlet还没有来得及把这个模块的mapping设置到请求中,自然找不到该模块的action。

        因此,这就引出一个约定,就是系统中尽量避免对Jsp的直接访问,如果要访问也要通过action来forward。虽然看起来麻烦一点,但是安全性、健壮性都会有所提高。

from:http://dev.csdn.net/article/55/55476.shtm

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模块里有

            path="/UserSecurityCheck"

       type="com.scs.presentation.security.UserSecurityCheckAction"

       name="UserLoginForm" scope="request"

       input="/init.do">

 

 

这个例子中,注意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.

我觉得好像是因为我新建了一个模块 struts-config-article.xml,貌似这个模块没有被装在进取。 我修改了以下web.xml,把两个模块合并就可以了,不知道为什么,对struts了解不多。

        <init-param>

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

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

                         /WEB-INF/struts-config-article.xml

            </param-value>

        </init-param>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值