用Java代理技术改造HttpServletRequest类

 

【文章标题】用Java代理技术改造HttpServletRequest

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

【作者声明】本人水平有限,失误之处,敬请各位指出。

*******************************************************************************

 

开发论坛中的模块通常有要解决以下两个问题:

1. 用户的发帖内容可能有一些特殊字符需要进行处理,如HTML的标记,又例如在04闹得沸沸扬扬的“SQL注入漏洞”,就是由于没有对用户提交的数据进行严格的检查而造成的。

2. 为了建设一个良好的论坛环境,防止用户输入不雅的文字,不然会影响论坛的气氛。

 

针对以上两个需要,可以对用户的提交信息进行过滤。

JavaWeb开发中,获取用户通过表单提交的信息一般的途径是使用request. getParameter函数获取提交的内容,接着就对所获取的字符串进行过滤,但这种做法做有一个问题:如果有多处需要进行过滤字符串的操作,难道每次都要重复写吗?有没有更方便的方法?

能否改造HttpServletRequest类,使得能先过滤getParameter函数获取的字符串后返回过滤后的结果呢?理论上没问题的,有一种设计模式叫“Decorator(装饰器)”模式(在本人的博文《打造山寨产品和伪造品的利器——装饰模式》对这种模式进行了讨论(http://blog.csdn.net/newjueqi)),初想一下能解决这个问题。于是就按照装饰器模式的方法进行改造。结果类的框架刚好搭建完毕就傻了眼,为啥,请看图1

                    

                                                 1

 

1只显示了MyHttpServletRequest_temp类需要实现包装的函数的一部分,总共有几十个函数需要重新包装一下,但本人想改写的只是函数getParameter难道为了重写这个方法就要把另外的几十个函数写一遍!

幸好JDK中有一门技术叫“动态代理”(Proxy),利用它能方便地实现我们的需求,使用动态代理能在普通方法调用前后增加处理方法,现在的AOP(Aspect Orient Program, 面向切面编程)就是以动态代理为基础的。

 

动态代理类主要的方法:

        public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
                               throws IllegalArgumentException

 

这个函数就是创建一个动态类的实例,各个参数的含义如下:

ClassLoader loader :类加载器对象

Class<?>[] interfaces:所实现的接口的Class对象

InvocationHandler h:这个是很重要的参数,定义了一个接口,实现其中的方法

 Object

invoke(Object proxy, Method method, Object[] args)

,能进行的具体代理操作。

 

编写后的完整的代码如下:

 

package newjueqi.net.csdn.filter;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

import javax.servlet.http.HttpServletRequest;

 

/**

 * 本类通过动态代理实现了对httpServletRequest中用getParameter函数获取的文字信息

 * 进行过滤

 *

 */

public class MyHttpServletRequest implements InvocationHandler {

 

       //被代理的类的引用

       private HttpServletRequest httpServletRequest;

 

       //传入需要被代理的类

       public MyHttpServletRequest( HttpServletRequest httpServletRequest)

       {

              this.httpServletRequest=httpServletRequest;

       }

      

       //获取动态代理实例

       public HttpServletRequest getInstance()

       {

              HttpServletRequest Request=null;

             

              Request=(HttpServletRequest)Proxy.

                     newProxyInstance(MyHttpServletRequest.class.getClassLoader(),

                                                  httpServletRequest.getClass().getInterfaces(),

                                                  

                                                  this );//自身实现了InvocationHandler接口,所以传this

             

              return Request;

       }

      

       /*

        * 过滤getParameter函数获取的文字信息

        */

       @Override

       public Object invoke(Object obj, Method method, Object[] arg)

                     throws Throwable {

             

              String value=null;

              Object result=null;

             

              //判断当前被调用的方法是否getParameter,如果是就进行信息过滤

              if( method.getName().equals("getParameter")  )

              {

                     value=httpServletRequest.getParameter( (String)arg[0]);

                    

                     //把“bad”替换为"***"

                     value=value.replaceAll("bad", "***");

                    

                     //返回替代后的结果

                     result=value;

              }

              else //如果不是调用方法“getParameter”就不正常处理

              {

                     result=method.invoke( httpServletRequest, arg );

              }

             

              return result;

       }

      

      

 

}

 

 

写了一个简单的页面测试,表单传递的信息含有需要过滤的字符”bad”,如图2

 

                                                        2

 

过滤后的信息如图3所示:

 

                                                        3

 

效果还是不错的^-^

当然了,这个类的过滤功能还可以进一步改进,例如把需要过滤的文字信息写在一个配置文件中,就能方便地维护。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newjueqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值