...
Code Block | ||
---|---|---|
| ||
<action name="Logon" class="tutorial.Logon"> <result type="redirectAction">Menu</result> <result name="input">/Logon.jsp</result> </action> |
When using Convention Plugin the action mapping can be configured with annotations:
...
Code Block | ||
---|---|---|
| ||
<s:form action="Hello"> <s:textfield label="Please enter your name" name="name"/> <s:submit/> </s:form> | ||
Info | ||
Action Names With Slashes
If your action names have slashes in them (for example, <action name="admin/home" class="tutorial.Admin"/>
) you need to specifically allow slashes in your action names via a constant in the struts.xml
file by specifying <constant name="struts.enable.SlashesInActionNames" value="true"/>
. See JIRA Issue WW-1383 for discussion as there are side effects to setting this property to true
.
...
Action Names with Dots and Dashes
Although action naming is pretty flexible, one should pay attention when using dots (eg. create.user) and/or dashes (eg. my-action). While the dot notation has no known side effects at this time, the dash notation will cause problems with the generated JavaScript for certain tags and themes. Use with caution, and always try to use camelcase action names (eg. createUser) or underscores (eg. my_action).
Action Methods
The default entry method to the handler class is defined by the Action interface.
Code Block | ||
---|---|---|
| ||
public interface Action {
public String execute() throws Exception;
}
|
Implementing the Action interface is optional. If Action is not implemented, the framework will use reflection to look for an execute
method.
Sometimes, developers like to create more than one entry point to an Action. For example, in the case of a data-access Action, a developer might want separate entry-points for create
, retrieve
, update
, and delete
. A different entry point can be specified by the method
attribute.
...
<action name="delete" class="example.CrudAction" method="delete">
...
Allowed action names
DefaultActionMapper
is using pre-defined RegEx to check if action name matches allowed names. The default RegEx is defined as follow: [a-zA-Z0-9._!/\-]*
- if at some point this doesn't match your action naming schema you can define your own RegEx and override the default using constant named struts.allowed.action.names
, e.g.:
Code Block | ||||
---|---|---|---|---|
| ||||
<struts>
<constant name="struts.allowed.action.names" value="[a-z{}]"*/>
...
</struts> |
NOTE: Please be aware that action names not matching the RegEx will rise an exception.
Action Methods
The default entry method to the handler class is defined by the Action interface.
Code Block | ||
---|---|---|
| ||
public interface Action {
public String execute() throws Exception;
}
|
Implementing the Action interface is optional. If Action is not implemented, the framework will use reflection to look for an execute
method.
Sometimes, developers like to create more than one entry point to an Action. For example, in the case of a data-access Action, a developer might want separate entry-points for create
, retrieve
, update
, and delete
. A different entry point can be specified by the method
attribute.
Code Block | ||||
---|---|---|---|---|
| ||||
<action name="delete" class="example.CrudAction" method="delete">
...
|
If there is no execute
method and no other method specified in the configuration the framework will throw an exception.
Convention Plugin allows that by annotating methods:
Code Block | ||
---|---|---|
| ||
@Action("crud")
public class CrudAction {
@Action("delete")
public String delete() {
...
|
Wildcard Method
Many times, a set of action mappings will share a common pattern. For example, all your edit
actions might start with the word "edit", and call the edit
method on the Action class. The delete
actions might use the same pattern, but call the delete
method instead.
Rather than code a separate mapping for each action class that uses
If there is no execute
method and no other method specified in the configuration the framework will throw an exception.
Convention Plugin allows that by annotating methods:
Code Block | ||
---|---|---|
| ||
@Action("crud")
public class CrudAction {
@Action("delete")
public String delete() {
...
|
Wildcard Method
Many times, a set of action mappings will share a common pattern. For example, all your edit
actions might start with the word "edit", and call the edit
method on the Action class. The delete
actions might use the same pattern, but call the delete
method instead.
Rather than code a separate mapping for each action class that uses this pattern, you can write it once as a wildcard mapping.
...
In Struts 2.5 the Strict DMI was extended and it's called "Strict Method Invocation" aka 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:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//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:
...
//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<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]*)"/>
Note |
---|
When using wildcard mapping in actions' definitions SMI works in two ways:
|
...
You can configure SMI per <action/>
usinf using <allowed-methods/>
tag or via @AllowedMethod
annotation plus using per <package/>
<global-allowed-methods/>
, see the examples below:
...
Code Block | ||||
---|---|---|---|---|
| ||||
@org.apache.struts2.convention.annotation.AllowedMethods({"home", "start"}) package org.apache.struts2.convention.actions.allowedmethods; |
Allowed methods can be defined as:
literals ie.
execute,cancel
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>
...