zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    Oracle数据库入门——体系结构
    基础知识——CentOS7操作系统的安装图文教程
    Oracle数据库入门——基础知识
    Windows Server 2008 R2 64位操作系统安装Oracle 11g 64位数据库,在客户终端上安装Oracle 11g 32位,才能安装P/L Sql Developer并配置
    2. Mysql数据库的入门知识
    1. Mysql数据库的安装
    Excel制作考勤管理
    常用函数公式及技巧搜集
    调试C++NPv2_Select_Reactor_Log_Server程序
    调试C++NPv2_Reactor_Log_Server程序
  • 原文地址:https://www.cnblogs.com/softidea/p/5904831.html
Copyright © 2011-2022 走看看