`
san586
  • 浏览: 134713 次
  • 性别: 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()

分享到:
评论
发表评论

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

相关推荐

    ss3ex中使用UrlRewrite

    在SS3EX框架中,UrlRewrite的使用是为了解决传统URL模式中参数过多、过于复杂的问题,提供一种更简洁、更美观的URL表示方式。下面将详细介绍SS3EX中使用UrlRewrite的相关知识点。 首先,URL重写主要是通过配置文件...

    发布ss3ex的maven版本,取名叫sango吧

    总结来说,这个项目是关于将ss3ex转换成一个支持Maven的Java项目,便于管理和构建,同时也可能提供了一种工具,帮助开发者在他们的工作中更高效地使用或集成ss3ex。通过博客链接提供的信息,读者可以深入了解这个...

    SSD3ex2答案

    2007卡耐基软件工程网路教材 SSD3ex2答案

    ssd3ex5练习5

    ssd3ex5源码,自己写的,保证100分!

    springside3+ext源代码

    文件列表中的"ss3ex.bmp"可能是一个项目标识或图标,它可能包含了项目的视觉元素,帮助识别项目。而"ss3ex"可能是项目的主干代码或者扩展模块,包含了对SpringSide3核心功能的增强和定制。 这个项目的源代码分析,...

    matlab开发-用matlab解题

    例如,`ch3ex6.m`, `ch3ex5.m`, `ch2ex3.m`, `ch4ex5a.m` 和 `ch2ex4.m` 可能是书中的练习题,每个对应一个特定章节的实例,可能涵盖了不同主题的MATLAB编程实践。 3. **图像处理**: 标签"图像处理与计算机视觉...

    maven版ibatis

    博客链接(https://ss3ex.iteye.com/blog/436901)可能包含了关于如何在Maven项目中集成和配置iBatis的实践教程,读者可以通过阅读该博客获取更具体的步骤和示例代码。 综上所述,"maven版ibatis"的主题涵盖了Maven...

    SSD3 EX1-7

    描述中提到的“源代码”表明该压缩包可能包含了用于教学目的的Java编程代码,这通常是为了实现特定的SSD管理功能或者进行性能测试。 在标签中,“SSD3”可能是课程的代号,而“JAVA”则指明了编程语言,这意味着...

    AIT存储助力盲人护助中心数据保护成功应用案例

    它以其高容量、高速度、低成本和可靠性获得了广泛应用,尤其是在非营利组织中,如科罗拉多盲人护助中心。 1. **高容量与高速度**: AIT-3Ex是Sony AIT系列的升级版本,提供了显著的存储性能提升。在未压缩状态下,...

    派特莱LCE-A 多层信号灯2D CAD Pole M2.pdf

    派特莱LCE-A 多层信号灯2D CAD Pole M2pdf,特点:高节能无需维护的LED多层信号灯,体积小可识别性强,特别匹配于各类中小型设备的外观设计。派特莱特有的混合棱镜切割灯罩,消除了可能存在的视觉盲点,大大提高了远...

    Sizzle v4.0.0.59

    Sizzle 是一套前端用智能来处理模块和组件依赖关系的框架。 它遵循 CommonJS 的运行规范来完成对各个模块的动态加载。...Sizzle 框架将被使用在 PJBlog4 新版本中,让后台更加代码逻辑化和模块化。

    C++实现显示MP3文件信息的方法

    在`main`函数中,我们检查命令行参数的数量,如果存在,则将第一个参数作为MP3文件的路径传递给`LoadFileID3Ex`函数。如果没有提供参数,程序将不会显示任何信息。 此外,注意到在代码中还有回调函数`CallbackFunc`...

    手机wap源码模板 (783).zip

    开发者可以根据需求对这些模板进行自定义修改,以适应特定的项目或品牌风格。同时,为了保证在各种设备上的兼容性和性能,还需要考虑响应式设计和优化,确保网站在不同分辨率和浏览器上都能良好运行。

    练习二(龙版)答案.doc

    3. **期望(数学期望)**(Expectation):随机变量的期望表示其平均值,如第4题中的EX=,第9题中的EX=np=1.6,第13题中的E(z)=3EX-2。 4. **方差(Variance)**:随机变量的方差衡量其数值离散程度,如第4题中的DX...

    OPPO r11 root 教程

    Root权限是指在Android操作系统中获取最高管理员权限,允许用户对系统的底层进行修改和控制。对于喜欢自定义手机系统的用户来说,Root权限能够提供更多的自由度和可能性。但需要注意的是,Root操作可能会导致手机...

    新健太郎通信协议(中文) - 副本1

    2. **适用**:此协议适用于所有使用HBP-9021/9020的通信场景,无论是在设备的开发阶段还是实际操作过程中。 3. **连接构成**:在PC与主CPU进行通信时,它们通过RS232C串行通信端口相连,具体是通过UART接口的TxD...

    新视角研究生英语读说写1部分答案

    【压缩包子文件的文件名称列表】中的文件可能分别对应课程的不同单元,如BI-U03_3EX.ppt可能是第三单元的练习讲解或答案解析,BI-U04_3EX.ppt可能是第四单元的内容。这些PPT文件可能包含了课件展示、习题解析、语言...

Global site tag (gtag.js) - Google Analytics