org.apache.struts2.dispatcher.mapper
public class: DefaultActionMapper [javadoc |
source]
java.lang.Object
org.apache.struts2.dispatcher.mapper.DefaultActionMapper
All Implemented Interfaces:
ActionMapper
Direct Known Subclasses:
Restful2ActionMapper
Default action mapper implementation, using the standard *.[ext] (where ext
usually "action") pattern. The extension is looked up from the Struts
configuration key
struts.action.exection.
To help with dealing with buttons and other related requirements, this
mapper (and other
ActionMapper s, we hope) has the ability to name a
button with some predefined prefix and have that button name alter the
execution behaviour. The four prefixes are:
- Method prefix - method:default
- Action prefix - action:dashboard
- Redirect prefix - redirect:cancel.jsp
- Redirect-action prefix - redirect-action:cancel
In addition to these four prefixes, this mapper also understands the
action naming pattern of
foo!bar in either the extension form (eg:
foo!bar.action) or in the prefix form (eg: action:foo!bar). This syntax tells
this mapper to map to the action named
foo and the method
bar.
Method Prefix
With method-prefix, instead of calling baz action's execute() method (by
default if it isn't overriden in struts.xml to be something else), the baz
action's anotherMethod() will be called. A very elegant way determine which
button is clicked. Alternatively, one would have submit button set a
particular value on the action when clicked, and the execute() method decides
on what to do with the setted value depending on which button is clicked.
<!-- START SNIPPET: method-example -->
<a:form action="baz">
<a:textfield label="Enter your name" name="person.name"/>
<a:submit value="Create person"/>
<a:submit name="method:anotherMethod" value="Cancel"/>
</a:form>
<!-- END SNIPPET: method-example -->
Action prefix
With action-prefix, instead of executing baz action's execute() method (by
default if it isn't overriden in struts.xml to be something else), the
anotherAction action's execute() method (assuming again if it isn't overriden
with something else in struts.xml) will be executed.
<!-- START SNIPPET: action-example -->
<a:form action="baz">
<a:textfield label="Enter your name" name="person.name"/>
<a:submit value="Create person"/>
<a:submit name="action:anotherAction" value="Cancel"/>
</a:form>
<!-- END SNIPPET: action-example -->
Redirect prefix
With redirect-prefix, instead of executing baz action's execute() method (by
default it isn't overriden in struts.xml to be something else), it will get
redirected to, in this case to www.google.com. Internally it uses
ServletRedirectResult to do the task.
<!-- START SNIPPET: redirect-example -->
<a:form action="baz">
<a:textfield label="Enter your name" name="person.name"/>
<a:submit value="Create person"/>
<a:submit name="redirect:www.google.com" value="Cancel"/>
</a:form>
<!-- END SNIPPET: redirect-example -->
Redirect-action prefix
With redirect-action-prefix, instead of executing baz action's execute()
method (by default it isn't overriden in struts.xml to be something else), it
will get redirected to, in this case 'dashboard.action'. Internally it uses
ServletRedirectResult to do the task and read off the extension from the
struts.properties.
<!-- START SNIPPET: redirect-action-example -->
<a:form action="baz">
<a:textfield label="Enter your name" name="person.name"/>
<a:submit value="Create person"/>
<a:submit name="redirect-action:dashboard" value="Cancel"/>
</a:form>
<!-- END SNIPPET: redirect-action-example -->
| Field Summary |
|---|
| static final String | METHOD_PREFIX | |
| static final String | ACTION_PREFIX | |
| static final String | REDIRECT_PREFIX | |
| static final String | REDIRECT_ACTION_PREFIX | |
| List | extensions | |
| Method from org.apache.struts2.dispatcher.mapper.DefaultActionMapper Summary: |
|---|
|
dropExtension, getDefaultExtension, getMapping, getUri, getUriFromActionMapping, handleSpecialParameters, isSlashesInActionNames, parseNameAndNamespace, setAllowDynamicMethodCalls, setAlwaysSelectFullNamespace, setContainer, setExtensions, setSlashesInActionNames |
| Method from org.apache.struts2.dispatcher.mapper.DefaultActionMapper Detail: |
String dropExtension(String name) {
if (extensions == null) {
return name;
}
Iterator it = extensions.iterator();
while (it.hasNext()) {
String extension = "." + (String) it.next();
if (name.endsWith(extension)) {
name = name.substring(0, name.length() - extension.length());
return name;
}
}
return null;
}
Drops the extension from the action name |
String getDefaultExtension() {
if (extensions == null) {
return null;
} else {
return (String) extensions.get(0);
}
}
Returns null if no extension is specified. |
public ActionMapping getMapping(HttpServletRequest request,
ConfigurationManager configManager) {
ActionMapping mapping = new ActionMapping();
String uri = getUri(request);
uri = dropExtension(uri);
if (uri == null) {
return null;
}
parseNameAndNamespace(uri, mapping, configManager);
handleSpecialParameters(request, mapping);
if (mapping.getName() == null) {
return null;
}
if (allowDynamicMethodCalls) {
// handle "name!method" convention.
String name = mapping.getName();
int exclamation = name.lastIndexOf("!");
if (exclamation != -1) {
mapping.setName(name.substring(0, exclamation));
mapping.setMethod(name.substring(exclamation + 1));
}
}
return mapping;
}
|
String getUri(HttpServletRequest request) {
// handle http dispatcher includes.
String uri = (String) request
.getAttribute("javax.servlet.include.servlet_path");
if (uri != null) {
return uri;
}
uri = RequestUtils.getServletPath(request);
if (uri != null && !"".equals(uri)) {
return uri;
}
uri = request.getRequestURI();
return uri.substring(request.getContextPath().length());
}
Gets the uri from the request |
public String getUriFromActionMapping(ActionMapping mapping) {
StringBuffer uri = new StringBuffer();
uri.append(mapping.getNamespace());
if (!"/".equals(mapping.getNamespace())) {
uri.append("/");
}
String name = mapping.getName();
String params = "";
if (name.indexOf('?") != -1) {
params = name.substring(name.indexOf('?"));
name = name.substring(0, name.indexOf('?"));
}
uri.append(name);
if (null != mapping.getMethod() && !"".equals(mapping.getMethod())) {
uri.append("!").append(mapping.getMethod());
}
String extension = getDefaultExtension();
if (extension != null) {
if (uri.indexOf('." + extension) == -1) {
uri.append(".").append(extension);
if (params.length() > 0) {
uri.append(params);
}
}
}
return uri.toString();
}
|
public void handleSpecialParameters(HttpServletRequest request,
ActionMapping mapping) {
// handle special parameter prefixes.
Set< String > uniqueParameters = new HashSet< String >();
Map parameterMap = request.getParameterMap();
for (Iterator iterator = parameterMap.keySet().iterator(); iterator
.hasNext();) {
String key = (String) iterator.next();
// Strip off the image button location info, if found
if (key.endsWith(".x") || key.endsWith(".y")) {
key = key.substring(0, key.length() - 2);
}
// Ensure a parameter doesn't get processed twice
if (!uniqueParameters.contains(key)) {
ParameterAction parameterAction = (ParameterAction) prefixTrie
.get(key);
if (parameterAction != null) {
parameterAction.execute(key, mapping);
uniqueParameters.add(key);
break;
}
}
}
}
Special parameters, as described in the class-level comment, are searched
for and handled. |
public boolean isSlashesInActionNames() {
return allowSlashesInActionNames;
}
|
void parseNameAndNamespace(String uri,
ActionMapping mapping,
ConfigurationManager configManager) {
String namespace, name;
int lastSlash = uri.lastIndexOf("/");
if (lastSlash == -1) {
namespace = "";
name = uri;
} else if (lastSlash == 0) {
// ww-1046, assume it is the root namespace, it will fallback to
// default
// namespace anyway if not found in root namespace.
namespace = "/";
name = uri.substring(lastSlash + 1);
} else if (alwaysSelectFullNamespace) {
// Simply select the namespace as everything before the last slash
namespace = uri.substring(0, lastSlash);
name = uri.substring(lastSlash + 1);
} else {
// Try to find the namespace in those defined, defaulting to ""
Configuration config = configManager.getConfiguration();
String prefix = uri.substring(0, lastSlash);
namespace = "";
// Find the longest matching namespace, defaulting to the default
for (Iterator i = config.getPackageConfigs().values().iterator(); i
.hasNext();) {
String ns = ((PackageConfig) i.next()).getNamespace();
if (ns != null && prefix.startsWith(ns) && (prefix.length() == ns.length() || prefix.charAt(ns.length()) == '/")) {
if (ns.length() > namespace.length()) {
namespace = ns;
}
}
}
name = uri.substring(namespace.length() + 1);
}
if (!allowSlashesInActionNames && name != null) {
int pos = name.lastIndexOf('/");
if (pos > -1 && pos < name.length() - 1) {
name = name.substring(pos + 1);
}
}
mapping.setNamespace(namespace);
mapping.setName(name);
}
Parses the name and namespace from the uri |
public void setAllowDynamicMethodCalls(String allow) {
allowDynamicMethodCalls = "true".equals(allow);
}
|
public void setAlwaysSelectFullNamespace(String val) {
this.alwaysSelectFullNamespace = "true".equals(val);
}
|
public void setContainer(Container container) {
this.container = container;
}
|
public void setExtensions(String extensions) {
if (!"".equals(extensions)) {
this.extensions = Arrays.asList(extensions.split(","));
} else {
this.extensions = null;
}
}
|
public void setSlashesInActionNames(String allow) {
allowSlashesInActionNames = "true".equals(allow);
}
|