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模块里有
    <action ></action >        path="/UserSecurityCheck"
       type="com.scs.presentation.security.UserSecurityCheckAction"
       name="UserLoginForm" scope="request"
       input="/init.do">
          <forward name="loginSucceed" path="/mainmenu.jsp"></forward>
   

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

<script type="text/javascript">&lt;!-- google_ad_client = &quot;pub-4348265167276910&quot;; /* 468x60, 个人博客 */ google_ad_slot = &quot;2046406163&quot;; google_ad_width = 468; google_ad_height = 60; //--&gt; </script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script><script src="http://pagead2.googlesyndication.com/pagead/expansion_embed.js"></script><script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script><script>google_protectAndRun(&quot;ads_core.google_render_ad&quot;, google_handleError, google_render_ad);</script>

2 楼 abin103 2008-04-14   引用
我也碰到了相同的问题
很急 不过看了你的文章 讲的太多了 能不能明了点啊
我也是 首先 访问的.jsp的 类似在 jsp里有个 login的 action
然后就出现  Cannot retrieve mapping for action /addProductType
[email protected] 欢迎加流
谢谢
1 楼 navaa 2007-11-28   引用
有时候可以通过一个什么都不做的局部刷新把一个应用的module config‘刷’回到另一个应用.


==============================
我解决了这个问题之后的配置。
struts-config.xml

<action-mappings >
    <action
      attribute="guestbookForm"
      input="/input.jsp"
      name="guestbookForm"
      parameter="method"
 
  path="/guestbook"  


      scope="request"
      type="org.springframework.web.struts.DelegatingActionProxy"  validate="false" />

  </action-mappings>
 


.jsp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:html xhtml="true" lang="true">
 


<body>
<html:form action="/guestbook.do  

?method=save"  onsubmit="return validateUserForm(this)">
  <html:hidden  property="method" value="save" />

		username:<html:text property="name" ></html:text>
		<html:errors property="name" />
	 
 
		 
     <html:submit value="提交">
           </html:submit>
   <html:javascript formName="UserForm" />  
</html:form>
</body>
</html:html>
 

你可能感兴趣的:(JavaScript,jsp,struts,MyEclipse,Google)