使用HttpServletRequestWrapper在filter修改request参数
Map<String, String[]> parameterMap = request.getParameterMap();不能被修改,原因如下:
/**
* 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为改地址的链接即可。
- <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 });
- }
- }
- }
- }
- }
- }
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进入两次:
***-----From QueryString-----***
userid=123456789
username=rensanning
***-----From ParameterMap-----***
username=rensanning,
userid=123456789,
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
(2)最终页面结果:
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
mycountry=china,
myname=rensanning,
- ForwardParameter.rar (4.8 KB)
http://rensanning.iteye.com/blog/1706208
使用HttpServletRequestWrapper在filter修改request参数的更多相关文章
- filter修改post参数
前景:公司项目web渗透测试中提出管理登录时,传输密码不能为明文,需要加密传输,但是迫于系统架构,后端代码不能修改,只能在filter中解密参数. 1.前端加密处理: <script type= ...
- 修改request请求参数
本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除: 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...
- 使用HttpServletRequestWrapper修改请求参数 和 使用HttpServletResponseWrapper截获响应数据
Servlet规范中的Filter引入了一个功能强大的拦截模式.Filter能在request到达servlet的服务方法之前拦截request对象,而在服务方法转移控制后又能拦截response对象 ...
- java修改request的paramMap
最近做项目,发现要修改request的参数内容.因为想要在request的paramMap里面默认注入,modifier和modifierName,这些内容.但是这个Map是不能修改的.所以采用了如下 ...
- 修改Request 中的数据
拦截器修改参数 今天一位网友开发中遇到一个需求,他需要在Request中修改传递过来的数据.开始的时候他在拦截器中修改,在拦截器中可以获取到从前台request中 传递过来的数据.他写法大致如下:自定 ...
- 通过zuul修改请求参数——对请求参数进行解密
zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用,Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架,Zuul 相当于是设备和 ...
- Java Web 修改请求参数
方法一.继承 HttpServletRequestWrapper , 实现自定义 request 1.除了修改的参数,其他 Header 等参数不变, 等同于修改了请求参数 2.实质是另一个请求 /* ...
- Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题
Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...
- Fiddler中设置断点修改Request和Response
Fiddler中设置断点修改Request Fiddler最强大的功能莫过于设置断点了,设置好断点后,你可以修改httpRequest 的任何信息包括host, cookie或者表单中的数据.设置断点 ...
随机推荐
- hdu2030java
汉字统计 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submissio ...
- mysql导出部分数据的几种方法(摘录)
mysql虽然可以使用mysqldump来进行数据的到处,可是在很多场合的需求都不一样,比如我只要导出某个字段呢?只要导出某些我需要的数据呢? 这个时候mysqldump可能就不大好使了 方法一. i ...
- android开发必备日志打印工具类
今天给大家献上一款好用的日志打印工具.大家在平时的开发中用的最多的可能就是Log.i("",""),Log.e("","" ...
- Android 自定义View修炼-自定义View-带百分比进度的圆形进度条(采用自定义属性)
很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如o ...
- windows 进程间通讯方法
Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式.共享文件方式.共享内存方式.共享数据段.映射文件方式.管道方式. 剪贴板方式.消息方式.其中注册表方式需要增加注册表表项,而注 ...
- MSDN无法显示该页的解决办法
今天打开msdn,发现 查阅api时候 出现 “无法显示该页的解决办法“ 这个问题.解决方案如下: 在“运行”中输入regsvr32 "C:\Program Files\Common Fil ...
- WisDom.Net 框架设计(七) 验证框架
WisDom.Net-验证框架 1.分类 这里我们将数据验证分为以下几种 数据类型校验 主要用于确保数据类型输入的正确 比如年龄一项输入 A岁 ,显然不合法 域检查 ...
- javascript 中状态改变触发事件
转 有限状态机:是一个非常有用的模型,可以模拟世界上大部分事物. 它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. * 某种条件下,会从一种状态转变(trans ...
- delphi 截取指定符号之间的字符串-随机读取
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...
- SQL反模式部分内容笔记
规范化: 1, 以一种我们能够理解的方式表达这个世界中的事物; 2, 减少数据冗余存储, 防止异常或者不一致的数据; 3, 支持完整性约束. Tips: 提高数据的性能不在此列表中. 意义: 规范化 ...