施用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为改地址的链接即可。
第二步:
新作Filter类:ParameterFilter,配置web.xml
在doFilter方法中包装request,设置新参数值。
包装类代码如下:
第三步:
sa的Servlet中,doGet()方法做forward跳转。
第四步:
sb的Servlet中生成页面输出所有QueryString和ParameterMap的参数。(代码略)
问题:
(1)Filter也只执行了一次
由于RequestDispatcher.forward是Servlet之间的跳转,所以默认不走Filter。在Servlet2.4规范中定义了可以在web.xml中配置:
(2)结果的QueryString中存在forward时URL的两个参数(myname、mycountry),而ParameterMap中没有。
forward时QueryString中的参数未被放入ParameterMap???
如下修改wrapper类:
再次运行代码:
(1)Filter进入两次:
(2)最终页面结果:
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
mycountry=china,
myname=rensanning,
处理过程:
(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,
***-----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,
***-----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,