修改HttpServletRequest的参数【转】

  当我们在做web应用的时候都会处理客户端提交到服务器的数据,如去除前后空格,一些非常字符,SQL注入类似的东西,在这里我主要说前后空格我是怎么来解决的,其它也都可以照此方法快速、方便、有效的解决,但是我一般对于非法字符,都是采用了标签来解决它的,并没有使用Filter转义掉(纯属个人解决办法)。
      去除前后空格看似非常简单的事,但是有许多人可能就是因为这一个小问题,折磨自己半天,客户端提交到所有的东西,都是以字符串形式提交的,我们不知道客户是怎么操作的,他可能把一个age属性对应的值,在输入时多加了一个空格,而服务器age对应的却是Integer类型,如果你使用servlet这事也好解决,但是如果你使用的是MVC框架,自动封装时就会得到一个类型转换异常,然而这个时候你是否有好的解决办法呢?
      这里我使用Filter来解决这一问题,这是最简单方便有效的解决方式,因为你不需要对每一个属性在封装前都去trim(),因为这是一件非常乏味的事情。大家都知道filter可以过滤我们想要它过滤的每一个请求,在这请求中有HttpServletRequest、HttpServletResponse。我们知道服务器取得客户端发送的参数都是通过HttpServletRequest来获取的,那我们可不可以在使用HttpServletRequest取值的时候就为每一个客户端提交的属性去除前后空格,或者其它的一些过滤操作。这肯定是可以的,那我们先来了解一下服务器是怎么取得客户端的值的。

1.getParameter(name),返回单个值。
2.getParameterValues(name),返回一个数组。
3.getParameterMap(),把客户端提交参数封装为一个Map返回。K:name,V:value。

      当我们使用servlet的时候一般都是使用前两种,struts1使用的第2种,struts2(xwork)则使用的第3种,那么我们只要在这三个方法调用的时候处理前后空格,那么返回到服务器的参数就又减少了一分出bug的机会,看下面的实现。

public   class  RequestParameterFilter  implements  Filter {

    
private   static  Log log  =  LogFactory.getLog(RequestParameterFilter. class );

    
private  List < String >  excludeNames;

    
public   void  destroy() {

    }

    
public   void  doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) 
throws  IOException, ServletException {
        
//
        request  =   new  HttpServletRequestWrapper2((HttpServletRequest) request);
        chain.doFilter(request, response);
    }

    
public   void  init(FilterConfig config)  throws  ServletException {
        String exclude 
=  config.getInitParameter( " exclude " );
        
//  not is null.
         if  (exclude  !=   null   &&  exclude.length()  >   0 ) {
            excludeNames 
=  Arrays.asList(exclude.split( " , " ));
            
if  (log.isDebugEnabled()) {
                log.debug(
" initialize arguments. " );
            }
        }
    }

    
/**
     * 该类继承之HttpServletRequestWrapper,并重写了对应取得客户端相当参数值的所有的方法。
     * <ul>
     * <li>getParameter</li>
     * <li>getParameterValues</li>
     * <li>getParameterMap</li>
     * </ul>
     * 
     * 
@version  1.0/2010-6-10 上午11:25:47
     * 
@author  Aidan
     * 
@see  HttpServletRequestWrapper
     
*/
    
private   class  HttpServletRequestWrapper2  extends  HttpServletRequestWrapper {

        
private  ParameterMap2 pm2;

        
public  HttpServletRequestWrapper2(HttpServletRequest request) {
            
super (request);
        }

        
public  String getParameter(String name) {
            
if  (excludeNames  !=   null   &&  excludeNames.contains(name)) {
                
return   super .getParameter(name);
            }
            
return  trim( super .getParameter(name));
        }

        @SuppressWarnings(
" unchecked " )
        
public  Map getParameterMap() {
            
//  xwork便使用此方法取值
            
//  该方法返回一个Map,Map映射了客户端请求对应的键值(K,V)。
             if  (pm2  ==   null ) {
                pm2 
=   new  ParameterMap2( super .getParameterMap());
            }
            
return  pm2;
        }

        
public  String[] getParameterValues(String name) {
            
//  Struts1使用此方法取得所有的参数值
             if  (excludeNames  !=   null   &&  excludeNames.contains(name)) {
                
return   super .getParameterValues(name);
            }
            
return  (String[]) trim( super .getParameterValues(name));
        }
    }

    
/**
     * 该此继承自HashMap。
     * 
     * 
@version  1.0/2010-6-10 上午11:30:13
     * 
@author  Aidan
     * 
@see  HashMap
     
*/
    @SuppressWarnings( { 
" unchecked " " serial "  })
    
private   class  ParameterMap2  extends  HashMap {

        
private  Set entrySet;

        
/**
         * 若要构造此类对象,则需要传入一个map参数,该map对应的客户端请求的参数(K,V)。
         * 
         * 
@param  map
         *            映射客户端参数。
         
*/
        
public  ParameterMap2(Map map) {
            
super (map);
        }

        
public  Set entrySet() {
            
//  xwork使用了此方法取值
             if  (entrySet  ==   null ) {
                entrySet 
=   new  HashSet();
                Set temSet 
=   super .entrySet();
                
for  (Iterator iterator  =  temSet.iterator(); iterator.hasNext();) {
                    Map.Entry me 
=  (Map.Entry) iterator.next();
                    Entry2 entry 
=   new  Entry2(me);
                    entrySet.add(entry);
                }
            }
            
return  entrySet;
        }

        
//  若直接从map使用key取得
         public  Object get(Object key) {
            Object value 
=   super .get(key);
            
//  不过滤此对象
             if  (excludeNames  !=   null   &&  excludeNames.contains(key)) {
                
return  value;
            }
            
if  (value  !=   null ) {
                
return  trim(value);
            }
            
return   null ;
        }
    }

    @SuppressWarnings(
" unchecked " )
    
private   class  Entry2 < K, V >   implements  Map.Entry < K, V >  {
        
private  Map.Entry me;
        
private   boolean  isTrim  =   true ;

        
public  Entry2(Map.Entry me) {
            
if  (me  ==   null ) {
                
throw   new  IllegalArgumentException(
                        
" Map.Entiry argument not null. " );
            }
            
this .me  =  me;
            
//  不过滤此对象
             if  (excludeNames  !=   null   &&  excludeNames.contains(me.getKey())) {
                isTrim 
=   false ;
            }
        }

        
public  K getKey() {
            
return  (K) me.getKey();
        }

        
public  V getValue() {
            
if  (isTrim) {
                
return  (V) trim(me.getValue());
            }
            
return  (V) me.getValue();
        }

        
public  V setValue(V value) {
            
return  (V) me.setValue(value);
        }

    }

    
/**
     * 去除一个Object类型对应的前后空格,因为客户端提交参数有两种,一种:String,另一种:String[],此方法会自动判断调用哪个方法。
     * 
     * 
@param  value
     *            需要处理的参数。
     * 
@return  处理后的值。
     
*/
    
protected  Object trim(Object value) {
        
if  (value  instanceof  String[]) {
            
return  trim((String[]) value);
        }
        
return  trim(value.toString());
    }

    
/**
     * 去除某个字符串的前后空格。
     * 
     * 
@param  value
     *            需要处理的参数。
     * 
@return  处理后的值。
     
*/
    
protected  String trim(String value) {
        
if  (value  !=   null   &&  value.length()  >   0 ) {
            
return  value.trim();
        }
        
return  value;
    }

    
/**
     * 去除某个数组中所有的值的前后空格。
     * 
     * 
@param  values
     *            需要处理的数组。
     * 
@return  处理后的值,当数组的length为1时,则返回一个String,反之返回一个数组。
     
*/
    
protected  Object trim(String[] values) {
        
if  (values  !=   null   &&  values.length  >   0 ) {
            
int  len  =  values.length;
            
for  ( int  i  =   0 ; i  <  len; i ++ ) {
                values[i] 
=  trim(values[i]);
            }
        }
        
if  (values.length  ==   1 ) {
            
return  values[ 0 ];
        }
        
return  values;
    }

    
/**
     * 
     * 
@return  不处理的对象。
     
*/
    
public  List < String >  getExcludeNames() {
        
return  excludeNames;
    }

}

      这个Filter实现原理非常简单,我会过滤所有的请求,HttpServletRequestWrapper2继承自HttpServletRequestWrapper,在构造函数中需要一个HttpServletRequest对象(这个request是web窗口创建的),然后我重载了上面所说的3个方法,在方法内部每次会去过滤当前值,这是利用了Java多态特性。在使用getParameterMap时较为麻烦,原理一样。
      当然我们有时候可能有些特殊情况不需要过滤前后空格或者其它一些规则,这里我们可以使用exclude属性来判断是否过滤此属性。
DEMO:

< form  action ="test!create.action"  method ="post" >
            name:
            
< input  name ="name"  value =" My name is haha.. "   />
            
< br  />
            
<!--  This is a String,isn't number.  -->
            age:
            
< input  name ="age"  value ="   15  "   />
            
< br  />
            email:
            
< input  name ="email"  value =" grasszring@gmail.com "   />
            
< br  />
            email2:
            
< input  name ="email"  value =" grasszring@foxmail.com "   />
            
< br  />
            
< input  type ="submit"  value =" submit "   />
</ form >

web.xml

< filter >
        
< filter-name > requestParameter </ filter-name >
        
< filter-class > com.onlyeffort.commons.web.filter.RequestParameterFilter </ filter-class >
        
< init-param >
            
<!--  不需要过滤此参数  -->
            
< param-name > exclude </ param-name >
            
< param-value > email </ param-value >
        
</ init-param >
    
</ filter >
    
< filter-mapping >
        
< filter-name > requestParameter </ filter-name >
        
< url-pattern > /* </ url-pattern >
</ filter-mapping >

action

@Action(params  =  {  " actionName " " test "  })
@Result(location 
=   " http://www.google.com " , type  =   " redirect " )
@SuppressWarnings(
" serial " )
public   class  TestController  extends  ActionSupport {

    
private  String name;
    
private  Integer age;
    
private  String[] email;
        
// .. get set method.

    @Override
    
public  String create()  throws  CreateFailureException {
        System.out.println(name);
        System.out.println(age);
        
for  (String mail : email) {
            System.out.println(mail);
        }        
        
return  SUCCESS;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值