施用HttpServletRequestWrapper在filter修改request参数

使用HttpServletRequestWrapper在filter修改request参数
处理过程:
(1)页面提交请求“/sa?userid=123456789&username=rensanning”
(2)通过Filter处理加入新参数“name=newname”
(3)sa的Servlet中forward到“/sb?myname=rensanning&mycountry=china”
(4)sb的Servlet中生成页面输出所有参数:userid、username、myname、mycountry、name

第一步:
最简单,在页面上先输出一个href为改地址的链接即可。
<a href="<%=request.getContextPath()%>/sa?userid=123456789&username=rensanning">Click me!!!</a>


第二步:
新作Filter类:ParameterFilter,配置web.xml
<filter-mapping>
	<filter-name>ParameterFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>


在doFilter方法中包装request,设置新参数值。
Map<String,String[]> m = new HashMap<String,String[]>(req.getParameterMap());
m.put("name", new String[]{"newname"});
req = new ParameterRequestWrapper((HttpServletRequest)req, m);

chain.doFilter(req, res);


包装类代码如下:
class ParameterRequestWrapper extends HttpServletRequestWrapper {

	private Map<String, String[]> params;

	public ParameterRequestWrapper(HttpServletRequest request,
			Map<String, String[]> newParams) {
		super(request);
		
		this.params = newParams;
	}

	@Override
	public String getParameter(String name) {
		String result = "";
		
		Object v = params.get(name);
		if (v == null) {
			result = null;
		} else if (v instanceof String[]) {
			String[] strArr = (String[]) v;
			if (strArr.length > 0) {
				result =  strArr[0];
			} else {
				result = null;
			}
		} else if (v instanceof String) {
			result = (String) v;
		} else {
			result =  v.toString();
		}
		
		return result;
	}

	@Override
	public Map getParameterMap() {
		return params;
	}

	@Override
	public Enumeration getParameterNames() {
		return new Vector(params.keySet()).elements();
	}

	@Override
	public String[] getParameterValues(String name) {
		String[] result = null;
		
		Object v = params.get(name);
		if (v == null) {
			result =  null;
		} else if (v instanceof String[]) {
			result =  (String[]) v;
		} else if (v instanceof String) {
			result =  new String[] { (String) v };
		} else {
			result =  new String[] { v.toString() };
		}
		
		return result;
	}

}


第三步:
sa的Servlet中,doGet()方法做forward跳转。
RequestDispatcher rd = getServletContext().getRequestDispatcher("/sb?myname=rensanning&mycountry=china");

rd.forward(request, response);


第四步:
sb的Servlet中生成页面输出所有QueryString和ParameterMap的参数。(代码略)

问题:
(1)Filter也只执行了一次

由于RequestDispatcher.forward是Servlet之间的跳转,所以默认不走Filter。在Servlet2.4规范中定义了可以在web.xml中配置:
<filter-mapping>
	<filter-name>ParameterFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>


(2)结果的QueryString中存在forward时URL的两个参数(myname、mycountry),而ParameterMap中没有。

forward时QueryString中的参数未被放入ParameterMap???

如下修改wrapper类:
class ParameterRequestWrapper extends HttpServletRequestWrapper {

	private Map<String, String[]> params;

	public ParameterRequestWrapper(HttpServletRequest request,
			Map<String, String[]> newParams) {
		super(request);
		
		this.params = newParams;

		// RequestDispatcher.forward parameter
		renewParameterMap(request);
	}

	@Override
	public String getParameter(String name) {
		String result = "";
		
		Object v = params.get(name);
		if (v == null) {
			result = null;
		} else if (v instanceof String[]) {
			String[] strArr = (String[]) v;
			if (strArr.length > 0) {
				result =  strArr[0];
			} else {
				result = null;
			}
		} else if (v instanceof String) {
			result = (String) v;
		} else {
			result =  v.toString();
		}
		
		return result;
	}

	@Override
	public Map getParameterMap() {
		return params;
	}

	@Override
	public Enumeration getParameterNames() {
		return new Vector(params.keySet()).elements();
	}

	@Override
	public String[] getParameterValues(String name) {
		String[] result = null;
		
		Object v = params.get(name);
		if (v == null) {
			result =  null;
		} else if (v instanceof String[]) {
			result =  (String[]) v;
		} else if (v instanceof String) {
			result =  new String[] { (String) v };
		} else {
			result =  new String[] { v.toString() };
		}
		
		return result;
	}

	private void renewParameterMap(HttpServletRequest req) {

		String queryString = req.getQueryString();

		if (queryString != null && queryString.trim().length() > 0) {
			String[] params = queryString.split("&");

			for (int i = 0; i < params.length; i++) {
				int splitIndex = params[i].indexOf("=");
				if (splitIndex == -1) {
					continue;
				}
				
				String key = params[i].substring(0, splitIndex);

				if (!this.params.containsKey(key)) {
					if (splitIndex < params[i].length()) {
						String value = params[i].substring(splitIndex + 1);
						this.params.put(key, new String[] { value });
					}
				}
			}
		}
	}

}


再次运行代码:
(1)Filter进入两次:
引用
URL:http://localhost:8080/t/sa
***-----From QueryString-----***
userid=123456789
username=rensanning
***-----From ParameterMap-----***
username=rensanning,
userid=123456789,


引用
URL:http://localhost:8080/t/sb
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,


(2)最终页面结果:
引用

***-----From QueryString-----***

myname=rensanning

mycountry=china




***-----From ParameterMap-----***

username=rensanning,

name=newname,

userid=123456789,

mycountry=china,

myname=rensanning,