动态代理解决表单提交的中文乱码问题

来源:互联网 发布:c语言随机数生成 编辑:程序博客网 时间:2024/06/08 03:36
        在上一篇播客中记录了使用装饰者设计模式来解决中文乱码问题,使用这种方式好在有一个已有的基类HttpServletRequestWrapper让我们继承,如果没有这个基类,则需要我们写大量的代码。

       而动态代理则能实现用哪个增强哪个,相对于使用装饰者模式,代码量简单,而且代码格式固定。 

我们经常说增强的方式常用的有:
1.继承
2.实现
3.动态代理
4.装饰者设计模式   

什么是动态代理呢?

       动态代理:在程序运行时  动态创建类  此类代表代理类。

要解决中文乱码问题,同样需要过滤器,在过滤器中使用动态代理。

具体代码如下:

final HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;request.setCharacterEncoding("utf-8");HttpServletRequest proxyRequest = (HttpServletRequest) Proxy.newProxyInstance(EncodeFilter.class.getClassLoader(),request.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//增强方法名为getParameter的方法if("getParameter".equals(method.getName())){//获取请求方式String method2 = request.getMethod();//判断是否为get请求if("GET".equalsIgnoreCase(method2)){//转码String val = request.getParameter(args[0].toString());//将转码后的结果返回return new String(val.getBytes("iso-8859-1"),"utf-8");}}//执行该方法return method.invoke(request, args);}});//放行chain.doFilter(proxyRequest, response);
结合上述代码分析各个参数的意义:

Proxy.newProxyInstance(参数1,参数2,参数3)

        参数1:当前类.getClass.getClassLoader

                     以前没有 proxyRequest 这个类 动态创建这个类出来 加载到内存 需要用到类加载器。 

        参数2:目标类.getClass.getInterfaces() 获得接口中的方法

                动态创建的类 没有方法 方法要和目标类一样 所以获得目标的类接口的方法。

        参数3:执行处理类

       代理类的方法跟目标类的方法一样 但没有实现,所以要有一个InvocatioHandler

       invoke(Object proxy, Method method, Object[] args)中的三个参数:

  参数1:Object proxy 代理对象
  参数2:Method method 代理对象当前执行的方法的描述对象

参数3:当前执行的方法的实际参数

需要记住的是:目标类每调用一次执行方法 就执行一次代理类的invoke

具体执行流程为:

        当请求过来时,先经过过滤器,之后过滤器放行,过滤器放行时传入的request对象时动态代理后的request对象。当进入servlet中时,servlet中调用request.getParameter方法获取请求的值时,由于这里的request对象已经换成我们使用动态代理生成的proxyRequest 对象,所以它会进入过滤器中执行new InvocationHandler()中的invoke方法 ,invoke方法中对原有的方法进行增强,从而解决乱码问题。



 

0 0
原创粉丝点击