javax.servlet.ServletRequest中的
Map<String, String[]> parameterMap = request.getParameterMap();不能被修改,原因如下:
org/apache/tomcat/embed/tomcat-embed-core/8.0.32/tomcat-embed-core-8.0.32-sources.jar!/org/apache/catalina/util/ParameterMap.java
    /**
* Associate the specified value with the specified key in this map. If
* the map previously contained a mapping for this key, the old value is
* replaced.
*
* @param key Key with which the specified value is to be associated
* @param value Value to be associated with the specified key
*
* @return The previous value associated with the specified key, or
* <code>null</code> if there was no mapping for key
*
* @exception IllegalStateException if this map is currently locked
*/
@Override
public V put(K key, V value) { if (locked)
throw new IllegalStateException
(sm.getString("parameterMap.locked"));
return (super.put(key, value)); }

https://my.oschina.net/cwalet/blog/35431

 
处理过程: 
(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为改地址的链接即可。

  1. <a href="<%=request.getContextPath()%>/sa?userid=123456789&username=rensanning">Click me!!!</a>

第二步: 
新作Filter类:ParameterFilter,配置web.xml

  1. <filter-mapping>
  2. <filter-name>ParameterFilter</filter-name>
  3. <url-pattern>/*</url-pattern>
  4. </filter-mapping>

在doFilter方法中包装request,设置新参数值。

  1. Map<String,String[]> m = new HashMap<String,String[]>(req.getParameterMap());
  2. m.put("name", new String[]{"newname"});
  3. req = new ParameterRequestWrapper((HttpServletRequest)req, m);
  4. chain.doFilter(req, res);

包装类代码如下:

  1. class ParameterRequestWrapper extends HttpServletRequestWrapper {
  2. private Map<String, String[]> params;
  3. public ParameterRequestWrapper(HttpServletRequest request,
  4. Map<String, String[]> newParams) {
  5. super(request);
  6. this.params = newParams;
  7. }
  8. @Override
  9. public String getParameter(String name) {
  10. String result = "";
  11. Object v = params.get(name);
  12. if (v == null) {
  13. result = null;
  14. } else if (v instanceof String[]) {
  15. String[] strArr = (String[]) v;
  16. if (strArr.length > 0) {
  17. result =  strArr[0];
  18. } else {
  19. result = null;
  20. }
  21. } else if (v instanceof String) {
  22. result = (String) v;
  23. } else {
  24. result =  v.toString();
  25. }
  26. return result;
  27. }
  28. @Override
  29. public Map getParameterMap() {
  30. return params;
  31. }
  32. @Override
  33. public Enumeration getParameterNames() {
  34. return new Vector(params.keySet()).elements();
  35. }
  36. @Override
  37. public String[] getParameterValues(String name) {
  38. String[] result = null;
  39. Object v = params.get(name);
  40. if (v == null) {
  41. result =  null;
  42. } else if (v instanceof String[]) {
  43. result =  (String[]) v;
  44. } else if (v instanceof String) {
  45. result =  new String[] { (String) v };
  46. } else {
  47. result =  new String[] { v.toString() };
  48. }
  49. return result;
  50. }
  51. }

第三步: 
sa的Servlet中,doGet()方法做forward跳转。

  1. RequestDispatcher rd = getServletContext().getRequestDispatcher("/sb?myname=rensanning&mycountry=china");
  2. rd.forward(request, response);

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

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

由于RequestDispatcher.forward是Servlet之间的跳转,所以默认不走Filter。在Servlet2.4规范中定义了可以在web.xml中配置:

  1. <filter-mapping>
  2. <filter-name>ParameterFilter</filter-name>
  3. <url-pattern>/*</url-pattern>
  4. <dispatcher>REQUEST</dispatcher>
  5. <dispatcher>FORWARD</dispatcher>
  6. </filter-mapping>

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

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

如下修改wrapper类:

  1. class ParameterRequestWrapper extends HttpServletRequestWrapper {
  2. private Map<String, String[]> params;
  3. public ParameterRequestWrapper(HttpServletRequest request,
  4. Map<String, String[]> newParams) {
  5. super(request);
  6. this.params = newParams;
  7. // RequestDispatcher.forward parameter
  8. renewParameterMap(request);
  9. }
  10. @Override
  11. public String getParameter(String name) {
  12. String result = "";
  13. Object v = params.get(name);
  14. if (v == null) {
  15. result = null;
  16. } else if (v instanceof String[]) {
  17. String[] strArr = (String[]) v;
  18. if (strArr.length > 0) {
  19. result =  strArr[0];
  20. } else {
  21. result = null;
  22. }
  23. } else if (v instanceof String) {
  24. result = (String) v;
  25. } else {
  26. result =  v.toString();
  27. }
  28. return result;
  29. }
  30. @Override
  31. public Map getParameterMap() {
  32. return params;
  33. }
  34. @Override
  35. public Enumeration getParameterNames() {
  36. return new Vector(params.keySet()).elements();
  37. }
  38. @Override
  39. public String[] getParameterValues(String name) {
  40. String[] result = null;
  41. Object v = params.get(name);
  42. if (v == null) {
  43. result =  null;
  44. } else if (v instanceof String[]) {
  45. result =  (String[]) v;
  46. } else if (v instanceof String) {
  47. result =  new String[] { (String) v };
  48. } else {
  49. result =  new String[] { v.toString() };
  50. }
  51. return result;
  52. }
  53. private void renewParameterMap(HttpServletRequest req) {
  54. String queryString = req.getQueryString();
  55. if (queryString != null && queryString.trim().length() > 0) {
  56. String[] params = queryString.split("&");
  57. for (int i = 0; i < params.length; i++) {
  58. int splitIndex = params[i].indexOf("=");
  59. if (splitIndex == -1) {
  60. continue;
  61. }
  62. String key = params[i].substring(0, splitIndex);
  63. if (!this.params.containsKey(key)) {
  64. if (splitIndex < params[i].length()) {
  65. String value = params[i].substring(splitIndex + 1);
  66. this.params.put(key, new String[] { value });
  67. }
  68. }
  69. }
  70. }
  71. }
  72. }
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector; /**
* Created by MyWorld on 2016/9/25.
*/
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
/**
* Constructs a request object wrapping the given request.
*
* @param request The request to wrap
* @throws IllegalArgumentException if the request is null
* http://www.cnblogs.com/softidea/p/5903873.html
*
*/
private Map<String, String[]> params; public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> params) {
super(request);
this.params = params;
addHeaderInfoToParams(request);
} private void addHeaderInfoToParams(HttpServletRequest request) {
request.getHeader("_pid"); } @Override
public String getParameter(String name) {
String[] values = getParameterValues(name);
if (values == null || values.length == 0) {
return null;
} else {
return values[0];
}
} @Override
public Map<String, String[]> getParameterMap() {
return params;
} @Override
public Enumeration<String> getParameterNames() {
return new Vector(params.keySet()).elements();
} @Override
public String[] getParameterValues(String name) {
String[] values = params.get(name);
if (values == null) {
return null;
} else {
return values;
}
} }
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; /**
* Created by MyWorld on 2016/9/25.
*/
public class AddExtraToParamsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Map<String, String[]> params = new HashMap<>(request.getParameterMap()); HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String pid = httpServletRequest.getHeader("_pid");
if (pid != null) {
params.put("pid", new String[]{pid});
}
request = new ParameterRequestWrapper(httpServletRequest, params);
chain.doFilter(request, response);
} @Override
public void destroy() {
}
}
 
再次运行代码: 
(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,

http://rensanning.iteye.com/blog/1706208

使用HttpServletRequestWrapper在filter修改request参数的更多相关文章

  1. filter修改post参数

    前景:公司项目web渗透测试中提出管理登录时,传输密码不能为明文,需要加密传输,但是迫于系统架构,后端代码不能修改,只能在filter中解密参数. 1.前端加密处理: <script type= ...

  2. 修改request请求参数

    本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除: 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...

  3. 使用HttpServletRequestWrapper修改请求参数 和 使用HttpServletResponseWrapper截获响应数据

    Servlet规范中的Filter引入了一个功能强大的拦截模式.Filter能在request到达servlet的服务方法之前拦截request对象,而在服务方法转移控制后又能拦截response对象 ...

  4. java修改request的paramMap

    最近做项目,发现要修改request的参数内容.因为想要在request的paramMap里面默认注入,modifier和modifierName,这些内容.但是这个Map是不能修改的.所以采用了如下 ...

  5. 修改Request 中的数据

    拦截器修改参数 今天一位网友开发中遇到一个需求,他需要在Request中修改传递过来的数据.开始的时候他在拦截器中修改,在拦截器中可以获取到从前台request中 传递过来的数据.他写法大致如下:自定 ...

  6. 通过zuul修改请求参数——对请求参数进行解密

    zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用,Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架,Zuul 相当于是设备和 ...

  7. Java Web 修改请求参数

    方法一.继承 HttpServletRequestWrapper , 实现自定义 request 1.除了修改的参数,其他 Header 等参数不变, 等同于修改了请求参数 2.实质是另一个请求 /* ...

  8. Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题

    Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...

  9. Fiddler中设置断点修改Request和Response

    Fiddler中设置断点修改Request Fiddler最强大的功能莫过于设置断点了,设置好断点后,你可以修改httpRequest 的任何信息包括host, cookie或者表单中的数据.设置断点 ...

随机推荐

  1. [Eclipse]The type XXX cannot be resolved. It is indirectly referenced from required .class files

    在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...

  2. angularjs 根据变量改变 动态加载模板

    directive return { restrict: 'E', replace: true, templateUrl: 'app/view/order.html', link: function ...

  3. wps批量使标题靠文档左边

  4. 在自定义的web监听器中嵌入web中的定时事件

    在 http://www.cnblogs.com/myadmin/p/4806265.html 中说明了自定义web监听器的一些东西. 本文中的web定时任务也基于上篇文章的自定义web监听器. 新建 ...

  5. HDU 1429 胜利大逃亡(续)(DP + 状态压缩)

    胜利大逃亡(续) Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢 ...

  6. Data Abstraction

    What is an object? (Page 238) In C++, an object is just a variable, and the purest definition is &qu ...

  7. Windows Phone 之手势识别(Flick)

    1. 引入dll (silverlight for wndows phone toolkit) 2.引入命名空间 01.xmlns:toolkit="clr-namespace:Micros ...

  8. Oracel用rownum实现真分页

    因为oracle的rownum是一个伪列,使用的时候如果要用必须查询出来显示的标记例如本sql中标记为 num. 值得一提的是最内层的这个查询sql:“select a.集团规范编码...”本身有一个 ...

  9. php 常用

    零:重要的PHP超级全局变量 1.$_SERVER $_SERVER超级全局变量包含由web服务器创建的信息,它提供了服务器和客户配置及当前请求环境的有关信息.根据服务器不同,$_SERVER中的变量 ...

  10. smarty模板引擎原理解析

    //php 控制器文件 <?php//引入模板引擎文件include("20130304.php");$smarty =newTinySmarty();$qq_numbers ...