使用HttpServletRequestWrapper在filter修改request参数

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.   
  5. chain.doFilter(req, res);  

包装类代码如下: 

 

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

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

Java代码  

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

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

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

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

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类: 

Java代码  

  1. class ParameterRequestWrapper extends HttpServletRequestWrapper {  
  2.   
  3.     private Map<String, String[]> params;  
  4.   
  5.     public ParameterRequestWrapper(HttpServletRequest request,  
  6.             Map<String, String[]> newParams) {  
  7.         super(request);  
  8.           
  9.         this.params = newParams;  
  10.   
  11.         // RequestDispatcher.forward parameter  
  12.         renewParameterMap(request);  
  13.     }  
  14.   
  15.     @Override  
  16.     public String getParameter(String name) {  
  17.         String result = "";  
  18.           
  19.         Object v = params.get(name);  
  20.         if (v == null) {  
  21.             result = null;  
  22.         } else if (v instanceof String[]) {  
  23.             String[] strArr = (String[]) v;  
  24.             if (strArr.length > 0) {  
  25.                 result =  strArr[0];  
  26.             } else {  
  27.                 result = null;  
  28.             }  
  29.         } else if (v instanceof String) {  
  30.             result = (String) v;  
  31.         } else {  
  32.             result =  v.toString();  
  33.         }  
  34.           
  35.         return result;  
  36.     }  
  37.   
  38.     @Override  
  39.     public Map getParameterMap() {  
  40.         return params;  
  41.     }  
  42.   
  43.     @Override  
  44.     public Enumeration getParameterNames() {  
  45.         return new Vector(params.keySet()).elements();  
  46.     }  
  47.   
  48.     @Override  
  49.     public String[] getParameterValues(String name) {  
  50.         String[] result = null;  
  51.           
  52.         Object v = params.get(name);  
  53.         if (v == null) {  
  54.             result =  null;  
  55.         } else if (v instanceof String[]) {  
  56.             result =  (String[]) v;  
  57.         } else if (v instanceof String) {  
  58.             result =  new String[] { (String) v };  
  59.         } else {  
  60.             result =  new String[] { v.toString() };  
  61.         }  
  62.           
  63.         return result;  
  64.     }  
  65.   
  66.     private void renewParameterMap(HttpServletRequest req) {  
  67.   
  68.         String queryString = req.getQueryString();  
  69.   
  70.         if (queryString != null && queryString.trim().length() > 0) {  
  71.             String[] params = queryString.split("&");  
  72.   
  73.             for (int i = 0; i < params.length; i++) {  
  74.                 int splitIndex = params[i].indexOf("=");  
  75.                 if (splitIndex == -1) {  
  76.                     continue;  
  77.                 }  
  78.                   
  79.                 String key = params[i].substring(0, splitIndex);  
  80.   
  81.                 if (!this.params.containsKey(key)) {  
  82.                     if (splitIndex < params[i].length()) {  
  83.                         String value = params[i].substring(splitIndex + 1);  
  84.                         this.params.put(key, new String[] { value });  
  85.                     }  
  86.                 }  
  87.             }  
  88.         }  
  89.     }  
  90.   
  91. }  
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

 

时间: 2024-10-26 21:48:37

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

Java Web 怎样修改request的参数值

问题描述 JavaWeb怎样修改request的参数值spring拦截器?过滤器?最好有实践过的给指定一下!!!谢谢大家!!! 解决方案 解决方案二:没有人遇到怎样的需求吗?解决方案三:具体是什么需求呢?解决方案四:引用1楼weiluo12的回复: 没有人遇到怎样的需求吗? JavaWeb怎样修改request的参数值在拦截器或者过滤器里面改变request参数的值!!!解决方案五:拦截器过滤器不可以么?解决方案六:用过滤器就可以实现,现在web.xml文件中配置好过滤器,自定义个一个过滤器,实

spring mvc-想把用户名存在session中 在方法中加request参数后运行报错 求指教~

问题描述 想把用户名存在session中 在方法中加request参数后运行报错 求指教~ 我用的是spring+hibernate~ 修改后: public class LoginAction extends SimpleFormController{ private Login login; private String viewPage; private String successPage; //实现onSubmit()方法 public ModelAndView onSubmit(Ob

AIX下修改maxuproc参数解决TNS-00519错误

一个AIX系统,内存16G,安装oracle数据库,刚刚应用上线,就发现了问题. 1.问题现象 客户端无法连接到数据库,listener运行正常,但是,在重新启动listener后报出如下错误: TNS-12549: TNS:operating system resource quota exceeded  TNS-12560: TNS:protocol adapter error   TNS-00519: Operating system resource quota exceeded    

JS 修改URL参数

本篇文章是对JS修改URL参数的实现代码进行了详细的分析介绍,需要的朋友参考下   复制代码 代码如下: function changeURLPar(url, ref, value) {     var str = "";     if (url.indexOf('?') != -1)         str = url.substr(url.indexOf('?') + 1);     else         return url + "?" + ref + &

【LINUX 学习】指定与修改挂载参数

指定与修改挂载参数 参数 -V 显示程序版本 -h 显示辅助讯息 -v 显示较讯息,通常和 -f 用来除错. -a  将 /etc/fstab 中定义的所有档案系统挂上. -F        这个命令通常和 -a 一起使用,它会为每一个 mount 的动作产生一个行程负责执行.在系统需要挂上大量 NFS 档案系统时可以加快挂上的动作. -f      通常用在除错的用途,它会使mount并不执行实际挂上的动作,而是模拟整个挂上的过程.通常会和-v一起使用.     -n      一般而言,mo

Symfony实现行为和模板中取得request参数的方法_php实例

本文实例讲述了Symfony实现行为和模板中取得request参数的方法.分享给大家供大家参考,具体如下: 一.模板中取得参数 <?php echo $sf_request->getParameter('name','namespace');?> <?php echo $sf_request->getParameter('name');?> 二.行为中取得参数 $request->getParameter('name'); //模板中取得参数 <?php e

hadoop修改哪个参数可以使fileinputformat可以读取子文件夹下的内容

问题描述 hadoop修改哪个参数可以使fileinputformat可以读取子文件夹下的内容 hadoop修改哪个参数可以使fileinputformat可以读取子文件夹下的内容

编程-Xposed开发 如何修改通过参数传值的函数的参数?

问题描述 Xposed开发 如何修改通过参数传值的函数的参数? 如题,比如我要HOOK一个函数 其返回值是一个int类型,表示读取到byte[] b里面的内容的长度,而真正的内容在byte[] b里面,通过参数传递的.在函数执行前byte[] b是一个长度为1024的空数组. 执行后b读取到内容. 我想获取函数执行后b的内容并修改,但是失败了 按道理来说第一次的log应当能记录下函数执行后b的实际值,即函数所要传递的内容,但是得到的却是长度为1024的空数组. 第二次log确实得到了修改后的"r

app-我自己开发了一个WebView的App,工作需要,怎样修改内核参数,设置为默认的浏览器呢?

问题描述 我自己开发了一个WebView的App,工作需要,怎样修改内核参数,设置为默认的浏览器呢? 我用真机nexus5,尝试了开启root,然后去看data/Ssystem/package.XML,通过设置不同的默认浏览器,找哪个位置被修改了,但找不到.请问修改默认浏览器后,是哪个内核文件被修改了? 解决方案 http://blog.sina.com.cn/s/blog_4e1e357d0101bfjq.html 试一试