过滤器Filter

Posted icehand1214

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤器Filter相关的知识,希望对你有一定的参考价值。

Filter简介

filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理。

步骤:

  1. 编写一个类实现Filter接口
  2. 实现接口中尚未实现的方法
  3. 在web.xml中进行配置

举个??子:

 1 package com.boss.filter;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 
12 public class MyFilter implements Filter {
13 
14   @Override
15   //Filter创建的时候执行init方法
16   public void init(FilterConfig filterConfig) throws ServletException {
17     //1、获得web.xml中filter的名称
18     System.out.println(filterConfig.getFilterName());//MyFilter
19     //2、获得当前filter的初始化参数
20     //System.out.println(filterConfig.getInitParameter("code"));//1
21     //3、获得servletContext
22     filterConfig.getServletContext();
23 
24     System.out.println("init...");
25   }
26 
27   @Override
28   //doFilter是Filter的核心过滤的方法
29   //request: 内部封装的是客户端http请求的内容
30   //response: 代表的是响应
31   //FilterChain: 过滤器链对象
32   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
33     throws IOException, ServletException {
34 
35     System.out.println("running...");
36     //放行请求
37     chain.doFilter(request, response);
38   }
39 
40   @Override
41   //Filter对象销毁的时候执行destory方法
42   public void destroy() {
43     System.out.println("destroy...");
44   }
45 
46 }

web.xml:

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.boss.filter.MyFilter</filter-class>
        <!-- 
        <init-param>
            <param-name>code</param-name>
            <param-value>1</param-value>
        </init-param>
         -->
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Filter的API详解

Filter对象的接口方法

  • init(Filterconfig):代表filter对象初始化方法,filter对象创建时执行。
  • doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法。

     其中的参数ServletRequest/ServletResponse是每次在执行doFilter方法时web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request与response就是在访问目标资源的service方法时的request和response。FilterChain是过滤器链对象,通过该对象的doFilter方法可以放行该请求。chain对象根据配置的filter-mapping顺序依次执行filter。

     技术分享图片

  • destory():代表是filter销毁方法,当filter对象销毁时执行该方法。

Filter对象的生命周期

  • Filter何时创建:服务器启动时就创建该filter对象
  • Filter何时销毁:服务器关闭时filter销毁

Filter的配置

url-pattern(拦截路径):

  • 完全匹配  /myServlet,只有访问myServlet时才执行
  • 目录匹配  /aaa/bbb/* 
  • 扩展名匹配  *.abc *.jsp

注意:url-pattern可以使用servlet-name替代,也可以混用。

dispatcher(访问方式):

  • REQUEST:默认值,代表直接访问某个资源时执行filter
  • FORWARD:转发时才执行filter
  • INCLUDE: 包含资源时执行filter
  • ERROR:发生错误时 进行跳转时执行filter

举个??子:

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.boss.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

测试代码:

 1 package com.boss.servlet;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 public class TestFilter extends HttpServlet {
11 
12   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
13     IOException {
14     request.getRequestDispatcher("/index.jsp").forward(request, response);
15   }
16 
17   public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
18     IOException {
19     doGet(request, response);
20   }
21 }

此时当访问TestFilter时,过滤器只会执行一次,而不是两次。转发时不会执行过滤器,但是重定向会执行两次。

测试代码:

 1 package com.boss.servlet;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 public class TestFilter extends HttpServlet {
11 
12   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
13     IOException {
14     response.sendRedirect(request.getContextPath() + "/index.jsp");
15   }
16 
17   public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
18     IOException {
19     doGet(request, response);
20   }
21 }

Filter的作用

  • 公共代码的提取
  • 可以对request和response中的方法进行增强(装饰者模式/动态代理)
  • 进行权限控制

使用filter解决参数中文乱码

 1 package com.boss.filter;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12 
13 public class EncodingFilter implements Filter {
14 
15   @Override
16   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
17     throws IOException, ServletException {
18 
19     //request.setCharacterEncoding("UTF-8");
20 
21     //在传递request之前对request的getParameter方法进行增强
22     /*
23      * 装饰者模式(包装)
24      * 
25      * 1、增强类与被增强的类要实现统一接口
26      * 2、在增强类中传入被增强的类
27      * 3、需要增强的方法重写 不需要增强的方法调用被增强对象原来的
28      * 
29      */
30 
31     //被增强的对象
32     HttpServletRequest req = (HttpServletRequest) request;
33     //增强对象
34     EnhanceRequest enhanceRequest = new EnhanceRequest(req);
35     chain.doFilter(enhanceRequest, response);
36   }
37 
38   @Override
39   public void destroy() {
40   }
41 
42   @Override
43   public void init(FilterConfig filterConfig) throws ServletException {
44   }
45 }
 1 package com.boss.filter;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletRequestWrapper;
 7 
 8 //HttpServletRequestWrapper类是HttpServletRequest类的装饰类
 9 public class EnhanceRequest extends HttpServletRequestWrapper {
10   private HttpServletRequest request;
11 
12   public EnhanceRequest(HttpServletRequest request) {
13     super(request);
14     this.request = request;
15   }
16 
17   //对getParameter增强
18   @Override
19   public String getParameter(String name) {
20     String param = request.getParameter(name);//乱码
21     try {
22       param = new String(param.getBytes("iso8859-1"), "UTF-8");
23     } catch (UnsupportedEncodingException e) {
24       e.printStackTrace();
25     }
26     return param;
27   }
28 
29 }

web.xml

    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.boss.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

以上是关于过滤器Filter的主要内容,如果未能解决你的问题,请参考以下文章

基于内部片段的graphql过滤器(gatsbyJS)

使用Logstash filter grok过滤日志文件

servlet,过滤器,监听器,拦截器的区别

vue实现简单的过滤器

Scapy BPF 过滤器不工作

在着色器中访问时,OpenGL如何决定使用MAG_FILTER和MIN_Filter?