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. ASP.NET中如何实现负载均衡

    ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一,做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同 ...

  2. 【转】关于C#接口和抽象类的一些说明

    接口和抽象类 1.概念 什么是接口? 接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称.参数和返回值. 接口方法不能包含任何实现,CLR允许接口可以包含事件.属性.索引器. 一个类可以实现多个 ...

  3. Big Data應用:以"玩家意見"之數據分析來探討何謂"健康型線上遊戲"(上)

    首先,所有資料都可以從網路上找到,只是我做了一些分析與整理而已.純粹分享心得~~ 最近再做研究的時候我跟我的同事K先生在某次偶然的討論中發現了一件有趣的事情. [疑~~~~~~~新楓之谷的玩家人氣指數 ...

  4. wordpress密码生成与登录密码验证

    一.研究wordpress时wordpess的密码密码生成与登录密码验证方式很重要 WordPress密码已成为整合的首要目标,如何征服整合,就得了解WordPress密码算法. WordPress系 ...

  5. PHP的无限栏目分类

    自己在PHP的无线栏目分类上面就是搞了很久都没有明白,所以现在是趁着记忆力还没有完全的消退的时候速度的记录下来 这里讲解的是最简单的树形栏目,适合的是小中型的栏目分类需求 1.这里讲解的是针对是只要通 ...

  6. Windows Azure 试用 for 世纪互联运维

    前一段时间申请由世纪互联运维的和谐版Windows Azure的邀请嘛下来,今天花费了点时间注册了一下 注册邀请函, 根据提示输入邀请码之后会收到以下邮件 中国地区可选择建立的虚拟机,SQL Serv ...

  7. POJ 1185 状态压缩DP(转)

    1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...

  8. 深入了解jquery中的键盘事件

    很多时候,我们需要获取用户的键盘事件,下面就一起来看看jquery是如何操作键盘事件的. 一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() k ...

  9. 第一天的CI笔记

    1 CI不区分大小写2. http://xxx.com/index/[控制器名称]/[控制器里面方法的确名称]/[传入方法的参数 ]/ 3. 控制器及控制器类名称与文件名称一致, 继承 CI_Cont ...

  10. LESS快速入门

    Less 简介 简单来说,Less 就是让你在网页设计的时候,可以更方便地写 CSS 的工具. Less官网的说明: LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承,运算,函数. LES ...