自定义URL格式,本方法只是在模仿REST样的URL格式:
比如原先的某一URL为:http://localhost:8080/article/article!listItems.shtml?article.id=297ef77923fe21850123fe24f405000f,
现在改为了:http://localhost:8080/article/article/listItems/297ef77923fe21850123fe24f405000f.shtml。去掉了“!”和“?”,而且他比REST格式的URL还要实在些。
[list]
[*]1、域名/namespace/action的名字/方法名.shtml
[*]2、域名/namespace/action的名字/方法名/默认为id的参数值.shtml
[*]3、域名/namespace/action的名字/方法名/参数1的名字/参数1的值/参数2的名字/参数2的值…….shtml
[/list]
后缀“.shtml”根据需要可以去掉。与REST式URL的不同在于,优点:
[list]
[*]1、不仅限于零配置;
[*]2、URL中的方法名可以随意,不用像rest式的是默认约定的方法名;
[/list]
缺点:没有实现REST式XML等的功能,不过也可以实现。
实现思路及代码(照抄ss3ex中的代码):
1、写个自定义RestfulActionMapper 类,实现ActionMapper接口,其实也可以直接继承DefaultActionMapper,但是写的代码要多些。
}
2、修改struts.properties文件中的默认配置
3、在action中得到ActionMapping中的参数的方法,有2种办法,一是在action中写个方法,利用ServletActionContext.getActionMapping()得到:
比如:
二是:在getMapping方法中将ActionMapping中的参数压入request中,然后在action中定义同名的变量,生成GET,SET方法,然后就能直接引用了,比如:
比如原先的某一URL为:http://localhost:8080/article/article!listItems.shtml?article.id=297ef77923fe21850123fe24f405000f,
现在改为了:http://localhost:8080/article/article/listItems/297ef77923fe21850123fe24f405000f.shtml。去掉了“!”和“?”,而且他比REST格式的URL还要实在些。
[list]
[*]1、域名/namespace/action的名字/方法名.shtml
[*]2、域名/namespace/action的名字/方法名/默认为id的参数值.shtml
[*]3、域名/namespace/action的名字/方法名/参数1的名字/参数1的值/参数2的名字/参数2的值…….shtml
[/list]
后缀“.shtml”根据需要可以去掉。与REST式URL的不同在于,优点:
[list]
[*]1、不仅限于零配置;
[*]2、URL中的方法名可以随意,不用像rest式的是默认约定的方法名;
[/list]
缺点:没有实现REST式XML等的功能,不过也可以实现。
实现思路及代码(照抄ss3ex中的代码):
1、写个自定义RestfulActionMapper 类,实现ActionMapper接口,其实也可以直接继承DefaultActionMapper,但是写的代码要多些。
package com.utils;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.RequestUtils;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
/*
* 自定义URL格式
* @Author sanshang
*/
public class RestfulActionMapper implements ActionMapper {
protected static final Logger LOG = LoggerFactory
.getLogger(RestfulActionMapper.class);
String ACTION_EXT_NAME = ".shtml";
public ActionMapping getMapping(HttpServletRequest request,
ConfigurationManager configManager) {
String nameSpace = "";
String actionName = "";
String method = "";
HashMap<String, String> parameters = new HashMap<String, String>();
String uri = RequestUtils.getServletPath(request);
// 去掉后缀
if (!uri.endsWith(ACTION_EXT_NAME)) {
return null;
} else {
uri = uri.substring(0, uri.lastIndexOf(ACTION_EXT_NAME));
}
int nextSlash = uri.indexOf('/', 1);
if (nextSlash == -1) {
return null;
}
String[] parse = uri.split("[///]");
if (1 < parse.length) {
nameSpace = uri.substring(1, nextSlash);
}
if (2 < parse.length) {
actionName = parse[2];
}
if (3 < parse.length) {
method = parse[3];
int beginIndex = ("/" + nameSpace + "/" + actionName + "/" + method)
.length();
try {
if (uri.length() > beginIndex) {
StringTokenizer st = new StringTokenizer(uri
.substring(beginIndex + 1), "/");
boolean isNameTok = true;
String paramName = null;
String paramValue;
// check if we have the first parameter name
if ((st.countTokens() % 2) != 0) {
isNameTok = false;
paramName = "id";
}
while (st.hasMoreTokens()) {
if (isNameTok) {
paramName = URLDecoder.decode(st.nextToken(),
"UTF-8");
isNameTok = false;
} else {
paramValue = URLDecoder.decode(st.nextToken(),
"UTF-8");
if ((paramName != null) && (paramName.length() > 0)) {
parameters.put(paramName, paramValue);
}
isNameTok = true;
}
}
}
} catch (Exception e) {
LOG.warn("Cannot determine url parameters", e);
}
}
return new ActionMapping(actionName, "/"+nameSpace, method, parameters);
}
public ActionMapping getMappingFromActionName(String actionName) {
return new ActionMapping(actionName, null, null, null);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.struts2.dispatcher.mapper.ActionMapper#getUriFromActionMapping
* (org.apache.struts2.dispatcher.mapper.ActionMapping)
*/
public String getUriFromActionMapping(ActionMapping mapping) {
String base = mapping.getNamespace() + "/" + mapping.getName();
if (StringUtils.isNotBlank(mapping.getMethod())) {
base = base + "/" + mapping.getMethod();
}
for (Iterator iterator = mapping.getParams().entrySet().iterator(); iterator
.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
String name = (String) entry.getKey();
if (name.equals("id")) {
base = base + "/" + entry.getValue();
break;
}
}
return base;
}
}
2、修改struts.properties文件中的默认配置
# struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper
struts.mapper.class=com.utils.RestfulActionMapper
struts.enable.SlashesInActionNames=true
3、在action中得到ActionMapping中的参数的方法,有2种办法,一是在action中写个方法,利用ServletActionContext.getActionMapping()得到:
/*
* 得到ActionMapping中的参数,如果参数为空,就默认返回id的值
*/
protected String getParams(Object... key) throws Exception {
ActionMapping mapping = ServletActionContext.getActionMapping();
Map map = mapping.getParams();
if (null != map) {
if (key.length == 0) {
if (map.containsKey("id")) {
return map.get("id").toString();
}
return "";
} else {
return map.get(key[0].toString()).toString();
}
}
return "";
}
比如:
setPage(articleService.getAllArticleForPage(page, getParams()));
二是:在getMapping方法中将ActionMapping中的参数压入request中,然后在action中定义同名的变量,生成GET,SET方法,然后就能直接引用了,比如:
getId()
。