在Filter中使用动态代理解决请求中文乱码问题

使用动态代理解决请求中文乱码问题

1.增强一个类我们常用的几种解决方案:

1、继承
a) 优点简单
b) 必须有被增强类的实现类
2、装饰者模式
a) 要求:1实现相同的接口。2持有被增强的对象
b) 优点:不必知道被增强的实现是谁
c) 缺点:必须实现所有没被增强方法的原始对象的原样调用
3、动态代理
a) 要求:1实现相同接口,2持有被增强的对象
b) 优点:不必手动实现所有不增强方法的原样调用。对方法进行增强时有类似过滤器的功能。
c) 缺点:学习成本高。

代理(Proxy):
一个代理对象,可以拥有被增强类的所有方法,可以对其中的某些方法进行增强。
动态:程序运行时直接生成被增强的对象,而不需要开发被增强类。
区别:装饰者模式需要创建一个包装类,由此类来完成对被增强类的增强。而动态代理则是在运行过程中动态生成增强对象(其类是代理类也是自动生成的,运行结束即消失)

反射机制:Object Proxy.newProxyInstance()通过调用此方法创建并获得代理对象

1.创建一个jsp页面帮助我们传递参数
  <form action="${pageContext.request.contextPath }/login" method="GET">
          <input type="text" name="username"><br>
          <input type="submit" value="登录">
  </form>

2.创建一个Servlet处理请求

  ?
  import java.io.IOException;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  ?
  /**
   *
   */
  public class LoginServlet extends HttpServlet {
      private static final long serialVersionUID = 1L;
  ?

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          String username = request.getParameter("username");
          System.out.println(username);

      }
  ?

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doGet(request, response);
      }
  ?
  }

3.创建一个过滤器,用于过滤所有的请求路径

  package com.filter;
  ?
  import java.io.IOException;
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  import java.lang.reflect.Proxy;
  ?
  import javax.servlet.Filter;
  import javax.servlet.FilterChain;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServletRequest;
  ?
  /**
   * 利用动态代理解决中文乱码问题
   */
  public class ProxyEcodeFilter implements Filter {
  ?
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
              throws IOException, ServletException {
          // 使用动态代理来增强getParameter方法
          // 获取请求方式
          HttpServletRequest req = (HttpServletRequest) request;
          ClassLoader loader = null;
          try {
              loader = Class.forName("com.filter.ProxyEcodeFilter").getClassLoader();
          } catch (ClassNotFoundException e) {
  ?
              e.printStackTrace();
          }
          // 获取委托者实现的所有接口
          Class<?>[] interfaces = req.getClass().getInterfaces();
          HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(loader, interfaces,
                  new InvocationHandler() {
  ?
                      @Override
                      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                          // 判断方法名
                          String methodName = method.getName();
                          if ("getParameter".equals(methodName)) {
                              // 判断请求方式
                              String name = req.getMethod();
                              if (name.equals("POST")) {
  ?
                                  req.setCharacterEncoding("UT-8");
  ?
                                  Object object = method.invoke(req, args);
                                  return object;
                              } else if (name.equals("GET")) {
                                  String value = (String) method.invoke(req, args);
                                  byte[] bytes = value.getBytes("ISO-8859-1");
                                  value = new String(bytes, "UTF-8");
                                  return value;
                              }
                          }
                          // req的其他方法就让他按以前的方式执行
                          return method.invoke(req, args);
                      }
                  });
          // 把代理者放行
          chain.doFilter(proxy, response);
      }
  ?
      public void init(FilterConfig fConfig) throws ServletException {
  ?
      }
  ?
      public void destroy() {
  ?
      }
  }

测试结果:成功解决中文请求乱码问题**

原文地址:https://www.cnblogs.com/weolwy/p/9094107.html

时间: 2024-10-09 04:34:46

在Filter中使用动态代理解决请求中文乱码问题的相关文章

利用filter和动态代理解决全站乱码问题

1.利用filter和动态代理解决全站乱码问题 1.1filter的代码 package com.baowei.filter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.servlet.Filter; import javax.servlet

使用动态代理解决全局乱码

javaweb中常常遇到表单提交后,读取表单数据乱码,特别是从request域存取数据最为频繁 ,常用的解决方法就是设置全局乱码文件码通过Filter过滤.无论是post方式提交还是get方式都适用. 我用的JDK1.8,用了Lambda表达式,1.8以下的可以用匿名内部类代替 首先创建一个Filter文件,实现代码如下: package com.practice.web.filter; import javax.servlet.*; import javax.servlet.http.Http

使用Java中的动态代理实现数据库连接池

2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在 互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共同的问题:这些连接池的实现方法都不同程度地增加了与使用者之间的耦合度.很多的连接池 都要求用户通过其规定的方法获取数据库的连接,这一点我们可以理解,毕竟目前

java中的动态代理机制

在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的.下面通过代码来学习java中的动态代理技术. 首先定义一个接口: package com.aop.spring; /** * Created by xinfengyao on 16-2-29. */ public interface Perform { public void play(); } 实

Java语言中反射动态代理接口的解释与演示

Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

java反射机制中的动态代理

java反射机制中的动态代理 动态代理模式及其使用 步骤1:定义一个接口 //接口 interface Subject{ void action(); } 步骤2:定义一个接口的实现类,也就是被代理类 //被代理类 class RealSubject implements Subject { @Override public void action() { System.out.println("我是被代理类,请执行我"); } } 步骤3:定义一个实现InvocationHandle

Spring AOP中的动态代理

0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  Spring AOP中的动态代理机制 2.1 JdkDynamicAopProxy 2.2 CglibAopProxy 3 总结 0  前言 前一个季度旅游TDC的Thames服务有几次宕机,根据组内原因认真查找发现是数据库事务造成的,后来把服务中的事务配置全部去掉,服务恢复正常.根据这次教训,虽然现在还是很难确定是哪一个方面的真正原因,但是激

十分钟理解Java中的动态代理

十分钟帮助大家理解Java中的动态代理,什么是动态代理?感兴趣的小伙伴们可以参考一下 若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 一.概述1. 什么是代理我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家"委托"代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,"委托

项目中get/post请求中文乱码的解决方案

一.解决get请求中文乱码的方案: 方案(推荐)1: 一般情况下tomcat(8之前)服务器的编码默认是ISO8859-1,所以要对get请求提交的参数进行重新编码: String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8"); 方案(不推荐)2: 既然知道了tomcat服务器的编码默认是ISO8859-1,那么可以修改to