SpringBoot之Filter详解

本文深入探讨了SpringBoot中的Filter,解释了过滤器的作用,如预处理和后处理用户请求。介绍了Filter的生命周期,包括创建和销毁过程。此外,对比了Filter、拦截器和切面的区别,并详细阐述了如何配置和使用Filter,包括配置类和注解两种方式。文章还揭示了Filter的注册原理,涉及FilterRegistrationBean的使用及其在SpringBoot中的注册流程。
摘要由CSDN通过智能技术生成

上篇分析了Interceptor(拦截器),今天继续对Filter(过滤器)做一个分析。

何为过滤器

Filter是J2EE中来的,可以看做是Servlet的一种“加强版”,它主要用于对用户请求进行预处理和后处理,拥有一个典型的处理链。Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理。
通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截过滤。

过滤器作用

在JavaDoc中给出了几种过滤器的作用:

 * Examples that have been identified for this design are
 * 1) Authentication Filters, 即用户访问权限过滤
 * 2) Logging and Auditing Filters, 日志过滤,可以记录特殊用户的特殊请求的记录等
 * 3) Image conversion Filters,图像转换过滤器
 * 4) Data compression Filters ,数据转换
 * 5) Encryption Filters ,安全加密
 * 6) Tokenizing Filters ,词法分析
 * 7) Filters that trigger resource access events ,资源访问事件触发过滤器
 * 8) XSL/T filters 
 * 9) Mime-type chain Filter ,文件类型链过滤器

过滤器的生命周期

Filter的生命周期:
Filter的创建:

Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

Filter的销毁:

Web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

FilterConfig接口:

用户在配置filter时,可以使用为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:
  String getFilterName():得到filter的名称。
  String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.
  Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
  public ServletContext getServletContext():返回Servlet上下文对象的引用

过滤器、拦截器和切面

Filter过滤器:拦截web访问url地址。依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据。比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
Interceptor拦截器:拦截以 .action结尾的url,拦截Action的访问。依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于Web框架的调用。因此可以使用spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
Spring AOP拦截器:只能拦截Spring管理Bean的访问(业务层Service)
获取信息的区别
Filter与Interceptor联系与区别

  1. 拦截器是基于java的反射机制,使用代理模式,而过滤器是基于函数回调。
  2. 拦截器不依赖servlet容器,过滤器依赖于servlet容器。
  3. 拦截器只能对action起作用,而过滤器可以对几乎所有的请求起作用(可以保护资源)。
  4. 拦截器可以访问action上下文,堆栈里面的对象,而过滤器不可以。

调用顺序:

如上图,展示了三者的调用顺序Filter->Interceptor->Aspect->Controller。相反的是,当Controller抛出的异常的处理顺序则是从内到外的。因此我们总是定义一个注解@ControllerAdvice去统一处理控制器抛出的异常。如果一旦异常被@ControllerAdvice处理了,则调用拦截器的afterCompletion方法的参数Exception ex就为空了。
访问流程

使用过滤器

根据 Filter 注册方式的不同,有注解、配置两种使用方式。若使用的是 Servlet3.0+版本,则两种方式均可使用;若使用的是 Servlet2.5版本,则只能使用配置类方式。
自定义的过滤器都必须实现javax.Servlet.Filter接口,并重写接口中定义的三个方法:

void init(FilterConfig config):用于完成Filter的初始化。

void destory():用于Filter销毁前,完成某些资源的回收。

void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能,即对每个请求及响应增加的额外的预处理和后处理。执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。值得注意的是,chain.doFilter()方法执行之前为预处理阶段,该方法执行结束即代表用户的请求已经得到控制器处理。因此,如果在doFilter中忘记调用chain.doFilter()方法,则用户的请求将得不到处理。

1、配置方式实现过滤器:

先自定义filter实现Filter接口

import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
public class AccesLogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("AccesLogFilter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, Filt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值