`
san586
  • 浏览: 132921 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

ss3ex中的自定义URL格式

阅读更多
自定义URL格式,本方法只是在模仿REST样的URL格式:
比如原先的某一URL为:http://localhost:8080/article/article!listItems.shtml?article.id=297ef77923fe21850123fe24f405000f,
现在改为了:http://localhost:8080/article/article/listItems/297ef77923fe21850123fe24f405000f.shtml。去掉了“!”和“?”,而且他比REST格式的URL还要实在些。
  • 1、域名/namespace/action的名字/方法名.shtml
  • 2、域名/namespace/action的名字/方法名/默认为id的参数值.shtml
  • 3、域名/namespace/action的名字/方法名/参数1的名字/参数1的值/参数2的名字/参数2的值…….shtml

后缀“.shtml”根据需要可以去掉。与REST式URL的不同在于,优点:
  • 1、不仅限于零配置;
  • 2、URL中的方法名可以随意,不用像rest式的是默认约定的方法名;

缺点:没有实现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()

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics