• 过滤器


    为什么需要过滤器?

    在项目开发中,经常会涉及到重复代码的实现;如:判断用户是否登录,只有登录的用户才具有操作权限。

    解决这类问题有两种方式:

    1、抽取重复代码并封装,在用到的地方手动调用。

    2、使用过滤器。

    过滤器相关API

    |-- interface  Filter                过滤器核心接口
         Void  init(filterConfig);    初始化方法,在服务器启动时候执行
      Void  doFilter(request,response,filterChain);   过滤器拦截的业务处理方法
      Void destroy();               销毁过滤器实例时候调用

    |-- interface  FilterConfig   获取初始化参数信息

      String getInitParameter(java.lang.String name) ; //根据名字获取初始化参数

      Enumeration getInitParameterNames() //过去所有初始化参数的名字

    |-- interface  FilterChain     过滤器链参数;一个个过滤器形成一个执行链;

      void doFilter(ServletRequest request, ServletResponse response)  ;  执行下一个过滤器或放行

    过滤器执行流程

    (1)用户访问服务器。

    (2)过滤器对servlet请求进行拦截。

    (3)先进入过滤器进行过滤处理。

    (4)过滤器处理完后,放行;此时请求到达servlet/JSP.

    (5)servlet处理。

    (6)servlet处理完后,再回到过滤器,最后在由tomcat服务器响应用户;

    时序图:

    过滤器执行过程测试代码:

     1 public class HelloFilter implements Filter{
     2     
     3     // 创建实例
     4     public HelloFilter(){
     5         System.out.println("1. 创建过滤器实例");
     6     }
     7 
     8     @Override
     9     public void init(FilterConfig filterConfig) throws ServletException {
    10         System.out.println("2. 执行过滤器初始化方法");
    11         
    12         // 获取过滤器在web.xml中配置的初始化参数
    13         String encoding = filterConfig.getInitParameter("encoding");
    14         System.out.println(encoding);
    15         
    16         // 获取过滤器在web.xml中配置的初始化参数 的名称
    17         Enumeration<String> enums =  filterConfig.getInitParameterNames();
    18         while (enums.hasMoreElements()){
    19             // 获取所有参数名称:encoding、path
    20             String name = enums.nextElement();
    21             // 获取名称对应的值
    22             String value = filterConfig.getInitParameter(name);
    23             System.out.println(name + "	" + value);
    24         }
    25     }
    26 
    27     // 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
    28     @Override
    29     public void doFilter(ServletRequest request, ServletResponse response,
    30             FilterChain chain) throws IOException, ServletException {
    31         System.out.println("3. 执行过滤器业务处理方法");
    32         // 放行 (去到Servlet)
    33         // 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
    34         chain.doFilter(request, response);
    35         
    36         System.out.println("5. Servlet处理完成,又回到过滤器");
    37     }
    38 
    39     @Override
    40     public void destroy() {
    41         System.out.println("6. 销毁过滤器实例");
    42     }
    43 
    44 }
    View Code

    使用过滤器处理编码格式

     1 // 过滤器业务处理方法:处理的公用的业务逻辑操作
     2     @Override
     3     public void doFilter(ServletRequest req, ServletResponse res,
     4             FilterChain chain) throws IOException, ServletException {
     5         
     6         // 转型
     7         final HttpServletRequest request = (HttpServletRequest) req;    
     8         HttpServletResponse response = (HttpServletResponse) res;
     9         
    10         // 一、处理公用业务
    11         request.setCharacterEncoding("UTF-8");                    // POST提交有效
    12         response.setContentType("text/html;charset=UTF-8");
    13         
    14         /*
    15          * 出现GET中文乱码,是因为在request.getParameter方法内部没有进行提交方式判断并处理。
    16          * String name = request.getParameter("userName");
    17          * 
    18          * 解决:对指定接口的某一个方法进行功能扩展,可以使用代理!
    19          *      对request对象(目标对象),创建代理对象!
    20          */
    21         HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
    22                 request.getClass().getClassLoader(),         // 指定当前使用的累加载器
    23                 new Class[]{HttpServletRequest.class},         // 对目标对象实现的接口类型
    24                 new InvocationHandler() {                    // 事件处理器
    25                     @Override
    26                     public Object invoke(Object proxy, Method method, Object[] args)
    27                             throws Throwable {
    28                         // 定义方法返回值
    29                         Object returnValue = null;
    30                         // 获取方法名
    31                         String methodName = method.getName();
    32                         // 判断:对getParameter方法进行GET提交中文处理
    33                         if ("getParameter".equals(methodName)) {
    34                             
    35                             // 获取请求数据值【 <input type="text" name="userName">】
    36                             String value = request.getParameter(args[0].toString());    // 调用目标对象的方法
    37                             
    38                             // 获取提交方式
    39                             String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
    40                             
    41                             // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
    42                             if ("GET".equals(methodSubmit)) {
    43                                 if (value != null && !"".equals(value.trim())){
    44                                     // 处理GET中文
    45                                     value = new String(value.getBytes("ISO8859-1"),"UTF-8");
    46                                 }
    47                             } 
    48                             return value;
    49                         }
    50                         else {
    51                             // 执行request对象的其他方法
    52                             returnValue = method.invoke(request, args);
    53                         }
    54                         
    55                         return returnValue;
    56                     }
    57                 });
    58         
    59         // 二、放行 (执行下一个过滤器或者servlet)
    60         chain.doFilter(proxy, response);        // 传入代理对象
    61     }
    View Code

    使用过滤器处理无效数据

     1 public class DateFilter implements Filter {
     2     
     3     // 初始化无效数据
     4     private List<String> dirtyData;
     5     @Override
     6     public void init(FilterConfig filterConfig) throws ServletException {
     7         // 模拟几个数据
     8         dirtyData = new ArrayList<String>();
     9         dirtyData.add("NND");
    10         dirtyData.add("炸使馆");
    11     }
    12 
    13     @Override
    14     public void doFilter(ServletRequest req, ServletResponse res,
    15             FilterChain chain) throws IOException, ServletException {
    16         
    17         // 转型
    18         final HttpServletRequest request = (HttpServletRequest) req;    
    19         HttpServletResponse response = (HttpServletResponse) res;
    20         
    21         // 一、处理公用业务
    22         request.setCharacterEncoding("UTF-8");                    // POST提交有效
    23         response.setContentType("text/html;charset=UTF-8");
    24         
    25         HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
    26                 request.getClass().getClassLoader(),         // 指定当前使用的累加载器
    27                 new Class[]{HttpServletRequest.class},         // 对目标对象实现的接口类型
    28                 new InvocationHandler() {                    // 事件处理器
    29                     @Override
    30                     public Object invoke(Object proxy, Method method, Object[] args)
    31                             throws Throwable {
    32                         // 定义方法返回值
    33                         Object returnValue = null;
    34                         // 获取方法名
    35                         String methodName = method.getName();
    36                         // 判断:对getParameter方法进行GET提交中文处理
    37                         if ("getParameter".equals(methodName)) {
    38                             
    39                             // 获取请求数据值【 <input type="text" name="userName">】
    40                             String value = request.getParameter(args[0].toString());    // 调用目标对象的方法
    41                             
    42                             // 获取提交方式
    43                             String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
    44                             
    45                             // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
    46                             if ("GET".equals(methodSubmit)) {
    47                                 if (value != null && !"".equals(value.trim())){
    48                                     // 处理GET中文
    49                                     value = new String(value.getBytes("ISO8859-1"),"UTF-8");
    50                                 }
    51                             } 
    52                             
    53                             // 中文数据已经处理完: 下面进行无效数据过滤   
    54                             //【如何value中出现dirtyData中数据,用****替换】  
    55                             for (String data : dirtyData) {
    56                                 // 判断当前输入数据(value), 是否包含无效数据
    57                                 if (value.contains(data)){
    58                                     value = value.replace(data, "*****");
    59                                 }
    60                             }
    61                             // 处理完编码、无效数据后的正确数据
    62                             return value;
    63                         }
    64                         else {
    65                             // 执行request对象的其他方法
    66                             returnValue = method.invoke(request, args);
    67                         }
    68                         
    69                         return returnValue;
    70                     }
    71                 });
    72         
    73         // 二、放行 (执行下一个过滤器或者servlet)
    74         chain.doFilter(proxy, response);        // 传入代理对象
    75     }
    76 
    77 
    78 
    79     @Override
    80     public void destroy() {
    81         
    82     }
    83 }
    View Code

    web.xml文件中的配置

     1 <!--1.  编码处理过滤器配置
     2     <filter>
     3         <filter-name>encoding</filter-name>
     4         <filter-class>cn.itcast.a_loginFilter.EncodingFilter</filter-class>
     5     </filter>
     6     <filter-mapping>
     7         <filter-name>encoding</filter-name>
     8         <url-pattern>/*</url-pattern>
     9     </filter-mapping>
    10      -->
    11      
    12      <!-- 2. 无效数据过滤器配置 -->
    13      <filter>
    14          <filter-name>dataFilter</filter-name>
    15          <filter-class>cn.itcast.b_filter_data.DateFilter</filter-class>
    16      </filter>
    17      <filter-mapping>
    18          <filter-name>dataFilter</filter-name>
    19          <url-pattern>/*</url-pattern>
    20      </filter-mapping>
    View Code
  • 相关阅读:
    [leetCode]09.用两个栈实现队列
    ubuntu:无法获得锁;无法锁定管理目录
    [leetCode]07.重建二叉树
    [leetCode]剑指 Offer 06. 从尾到头打印链表
    [leetCode]剑指 Offer 05. 替换空格
    [leetCode]1330.翻转子数组得到最大的数组值
    [leetCode]312.戳气球
    UVALive
    CodeChef
    CodeChef
  • 原文地址:https://www.cnblogs.com/nicker/p/6820758.html
Copyright © 2020-2023  润新知