使用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>.
<?
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:
<?
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>/@AllowedMethodsis 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>/@AllowedMethodsare 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 intoallowedMethod = "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:
<
package
...>
...
<
global-allowed-methods
>execute,input,back,cancel,browse</
global-allowed-methods
>
...
<
action
name
=
"Bar"
>
<
allowed-methods
>foo,bar</
allowed-methods
>
</
action
>
...
</
package
>
|
@AllowedMethods
(
"end"
)
public
class
ClassLevelAllowedMethodsAction {
public
String execute() {
return
...
}
}
|
@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,cancelor 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.
本文分析了使用Struts2.5.2时遇到的404错误原因,指出这是由于StrictMethodInvocation(SMI)默认启用导致的。文中详细解释了如何通过配置<allowed-methods>来解决通配符映射问题。
4万+

被折叠的 条评论
为什么被折叠?



