使用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,在
附docs部分原文:
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
element. This tells Struts to reject any method that is not explicitly allowed via either the method
attribute (including wildcards) or the
tag. Then specify
as a comma-separated list of method names in your
. (If you specify a method
attribute for your action, you do not need to list it in
.)
Note that you can specify
even without strict-method-invocation
. This restricts access only for the specific actions that have
.
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<
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
>
|
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"
?>
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<
struts
>
...
struts
>
|
SMI works in the following way:
/ @AllowedMethods
is defined per action - SMI works without switching it on but just for those actions (plus adding
)
/ @AllowedMethods
are defined - SMI works but only with
([A-Za-z0-9_$]*)
You can redefine the default RegEx by using a constant as follow
When using wildcard mapping in actions' definitions SMI works in two ways:
will be translated into allowedMethod = "regex:perform([A-Za-z0-9_$]*)".
tag. You can configure SMI per
using
tag or via @AllowedMethod
annotation plus using per
, 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,cancel
or in annotation: {"
execute
", "cancel
"}
regex:
prefix, ie: execute,input,cancel,regex:user([A-Z]*)
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.