Struts 2.5.2 HTTP Status 404 - There is no Action mapped for namespace [/] and action name [regist_A

本文分析了使用Struts2.5.2时遇到的404错误原因,指出这是由于StrictMethodInvocation(SMI)默认启用导致的。文中详细解释了如何通过配置<allowed-methods>来解决通配符映射问题。
摘要由CSDN通过智能技术生成

使用Struts2.5.2   学习Action通配符时,出现错误:HTTP Status 404 - There is no Action mapped for namespace [/] and action name [regist_Action] associated with context path [/wildcard1].

在确保代码无误的情况下,用Struts2.3 JAR包代替后可正常使用,而Struts2.5不行,最后确定是Struts2.5.2 JAR本身的问题。

查看文档struts-2.5.2\docs\docs\action-configuration.html后找到问题所在。

首先,2.3版本中多了一个Strict DMI,当设置包属性strict-method-invocation="true" 时,Struts会拒绝一切不明确的方法属性包括通配符。(有点难翻译,具体看原文)

而2.5版本中的 Method Invocation(SMI)继承了2.3中的Strict DMI,属性strict-method-invocation被默认设置为true,所以才会出现这个错误。


解决方法:修改struts.xml,在<allowed-methods>准确添加method

<struts>
<package name="lee" extends="struts-default">
<action name="*_Action" class="org.crazyit.app.action.LoginRegistAction"
method="{1}">
<!-- 定义逻辑视图和物理视图之间的映射关系 -->
<result name="error">/WEB-INF/content/error.jsp</result>
<result>/WEB-INF/content/welcome.jsp</result>
<allowed-methods>login,regist</allowed-methods>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>


附docs部分原文:

Strict DMI

In Struts 2.3, an option was added to restrict the methods that DMI can invoke. First, set the attribute strict-method-invocation="true" on your <package> element. This tells Struts to reject any method that is not explicitly allowed via either the method attribute (including wildcards) or the <allowed-methods> tag. Then specify <allowed-methods> as a comma-separated list of method names in your <action>. (If you specify a method attribute for your action, you do not need to list it in <allowed-methods>.)

Note that you can specify <allowed-methods> even without strict-method-invocation. This restricts access only for the specific actions that have <allowed-methods>.

Example struts.xml
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE struts PUBLIC
     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
< struts >
 
   < constant name = "struts.enable.DynamicMethodInvocation" value = "true" />
 
   < package name = "default" extends = "struts-default" strict-method-invocation = "true" >
 
     < action name = "index" class = "org.apache.struts2.examples.actions.Index" >
         < result name = "success" type = "redirectAction" >hello</ result >
     </ action >
 
     < action name = "hello" class = "org.apache.struts2.examples.actions.HelloAction" >
         < result name = "success" >/WEB-INF/content/hello.jsp</ result >
         < result name = "redisplay" type = "redirectAction" >hello</ result >
         < allowed-methods >add</ allowed-methods >
     </ action >
 
   </ package >
</ struts >

Strict Method Invocation

In Struts 2.5 the Strict DMI was extended and it's called Strict Method Invocation aka SMI. You can imagine that the DMI is a "border police", where SMI is a "tax police" and keeps eye on internals. With this version, SMI is enabled by default (strict-method-invocation attribute is set to true by default in struts-default package), you have option to disable it per package - there is no global switch to disable SMI for the whole application. To gain advantage of new configuration option please use the latest DTD definition:

Struts 2.5 DTD
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE struts PUBLIC
         "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
< struts >
...
</ struts >

SMI works in the following way:

  • <allowed-methods> / @AllowedMethods is defined per action - SMI works without switching it on but just for those actions (plus adding <global-allowed-methods/>)
  • SMI is enabled but no <allowed-methods> / @AllowedMethods are defined - SMI works but only with <global-allowed-methods/>
  • SMI is disabled - call to any action method is allowed that matches the default RegEx - ([A-Za-z0-9_$]*)

You can redefine the default RegEx by using a constant as follow <constant name="struts.strictMethodInvocation.methodRegex" value="([a-zA-Z]*)"/>

When using wildcard mapping in actions' definitions SMI works in two ways:

  • SMI is disabled - any wildcard will be substituted with the default RegEx, ie.: <action name="Person*" method="perform*"> will be translated into allowedMethod = "regex:perform([A-Za-z0-9_$]*)".
  • SMI is enabled - no wildcard substitution will happen, you must strictly define which methods can be accessed by annotations or <allowed-method/> tag.

You can configure SMI per <action/> using <allowed-methods/> tag or via @AllowedMethod annotation plus using per <package/> <global-allowed-methods/>, see the examples below:

SMI via struts.xml
< package ...>
   ...
   < global-allowed-methods >execute,input,back,cancel,browse</ global-allowed-methods >
   ...
  
   < action name = "Bar" >
     < allowed-methods >foo,bar</ allowed-methods >
   </ action >
  
   ...
</ package >
SMI via annotation on action class level
@AllowedMethods ( "end" )
public class ClassLevelAllowedMethodsAction {
     public String execute() {
         return ...
     }
}
SMI via annotation on package level (in package-info.java)
@org .apache.struts2.convention.annotation.AllowedMethods({ "home" , "start" })
package org.apache.struts2.convention.actions.allowedmethods;

Allowed methods can be defined as:

  • literals ie. in xml: execute,cancel or in annotation: {"execute", "cancel"}

  • patterns when using with wildcard mapping, i.e <action ... method="do{2}"/>
  • RegExs using regex: prefix, ie: <global-allowed-methods>execute,input,cancel,regex:user([A-Z]*)</global-allowed-methods>

Please be aware when using your own Configurationprovider that the logic to set allowed methods is defined in built-in providers - XmlConfigurationProvider and PackageBasedActionConfigBuilder - and you must replicate such logic in your code as by default only execute method is allowed, even when SMI is disabled.






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值