Spring Boot拦截器和过滤器实例解析

这篇文章主要介绍了Spring Boot拦截器和过滤器实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、拦截器与过滤器

在讲Spring boot之前,我们先了解一下过滤器和拦截器。这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的。在分析两者的区别之前,我们先理解一下AOP的概念,AOP不是一种具体的技术,而是一种编程思想。在面向对象编程的过程中,我们很容易通过继承、多态来解决纵向扩展。 但是对于横向的功能,比如,在所有的service方法中开启事务,或者统一记录日志等功能,面向对象的是无法解决的。所以AOP——面向切面编程其实是面向对象编程思想的一个补充。而我们今天讲的过滤器和拦截器都属于面向切面编程的具体实现。而两者的主要区别包括以下几个方面:

  1、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

  2、Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。

  3、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

二、过滤器的配置

现在我们通过过滤器来实现记录请求执行时间的功能,其实现如下:

public class LogCostFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    long start = System.currentTimeMillis();
    filterChain.doFilter(servletRequest,servletResponse);
    System.out.println("Execute cost="+(System.currentTimeMillis()-start));
  }

  @Override
  public void destroy() {

  }
}

这段代码的逻辑比较简单,就是在方法执行前先记录时间戳,然后通过过滤器链完成请求的执行,在返回结果之间计算执行的时间。这里需要主要,这个类必须继承Filter类,这个是Servlet的规范,这个跟以前的Web项目没区别。但是,有了过滤器类以后,以前的web项目可以在web.xml中进行配置,但是spring boot项目并没有web.xml这个文件,那怎么配置?在Spring boot中,我们需要FilterRegistrationBean来完成配置。其实现过程如下:

@Configuration
public class FilterConfig {

  @Bean
  public FilterRegistrationBean registFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new LogCostFilter());
    registration.addUrlPatterns("/*");
    registration.setName("LogCostFilter");
    registration.setOrder(1);
    return registration;
  }

}

这样配置就完成了,需要配置的选项主要包括实例化Filter类,然后指定url的匹配模式,设置过滤器名称和执行顺序,这个过程和在web.xml中配置其实没什么区别,只是形式不同而已。现在我们可以启动服务器访问任意URL:

大家可以看到上面的配置已经生效了。除了通过 FilterRegistrationBean 来配置以外,还有一种更直接的办法,直接通过注解就可以完成了:

@WebFilter(urlPatterns = "/*", filterName = "logFilter2")
public class LogCostFilter2 implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    long start = System.currentTimeMillis();
    filterChain.doFilter(servletRequest, servletResponse);
    System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start));
  }

  @Override
  public void destroy() {

  }
}

这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式,过滤器名称等。这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在配置类中加另外一个注解:@ServletComponetScan,指定扫描的包。

@SpringBootApplication
@MapperScan("com.pandy.blog.dao")
@ServletComponentScan("com.pandy.blog.filters")
public class Application {
  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}

现在,我们再来访问一下任意URL:

可以看到,我们配置的两个过滤器都生效了。细心的读者会发现,第二个Filter我们并没有指定执行的顺序,但是却在第一个Filter之前执行。这里需要解释一下,@WebFilter这个注解并没有指定执行顺序的属性,其执行顺序依赖于Filter的名称,是根据Filter类名(注意不是配置的filter的名字)的字母顺序倒序排列,并且@WebFilter指定的过滤器优先级都高于FilterRegistrationBean配置的过滤器。有兴趣的朋友可以自己实验一下。

三、拦截器的配置

上面我们已经介绍了过滤器的配置方法,接下来我们再来看看如何配置一个拦截器。我们使用拦截器来实现上面同样的功能,记录请求的执行时间。首先我们实现拦截器类:

public class LogCostInterceptor implements HandlerInterceptor {
  long start = System.currentTimeMillis();
  @Override
  public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    start = System.currentTimeMillis();
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
  }

  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
  }
}

这里我们需要实现HandlerInterceptor这个接口,这个接口包括三个方法,preHandle是请求执行前执行的,postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。除了实现上面的接口外,我们还需对其进行配置:

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");
    super.addInterceptors(registry);
  }
}

这里我们继承了WebMVCConfigurerAdapter,看过前面的文章的朋友应该已经见过这个类了,在进行静态资源目录配置的时候我们用到过这个类。这里我们重写了addInterceptors这个方法,进行拦截器的配置,主要配置项就两个,一个是指定拦截器,第二个是指定拦截的URL。现在我们再启动系统访问任意一个URL:

可以看到,我们通过拦截器实现了同样的功能。不过这里还要说明一点的是,其实这个实现是有问题的,因为preHandle和postHandle是两个方法,所以我们这里不得不设置一个共享变量start来存储开始值,但是这样就会存在线程安全问题。当然,我们可以通过其他方法来解决,比如通过ThreadLocal就可以很好的解决这个问题,有兴趣的同学可以自己实现。不过通过这一点我们其实可以看到,虽然拦截器在很多场景下优于过滤器,但是在这种场景下,过滤器比拦截器实现起来更简单。

四、总结

本文主要对基于Spring boot对过滤器和拦截器的配置进行的讲解。无论是过滤器还是拦截器都属于AOP(面向切面编程)思想的具体实现。除了这两种实现我们还见过另一种更灵活的AOP实现技术,即Aspect,我们可以通过Aspect来完成更多更强大的功能。这个后续再给大家分享。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解

    本文通过一个简易安全认证示例的开发实践,理解过滤器和拦截器的工作原理. 很多文章都将过滤器(Filter).拦截器(Interceptor)和监听器(Listener)这三者和Spring关联起来讲解,并认为过滤器(Filter).拦截器(Interceptor)和监听器(Listener)是Spring提供的应用广泛的组件功能. 但是严格来说,过滤器和监听器属于Servlet范畴的API,和Spring没什么关系. 因为过滤器继承自javax.servlet.Filter接口,监听器继承自ja

  • SpringBoot实现过滤器、拦截器与切片的实现和区别

    Q:使用过滤器.拦截器与切片实现每个请求耗时的统计,并比较三者的区别与联系 过滤器Filter 过滤器概念 Filter是J2E中来的,可以看做是 Servlet 的一种"加强版",它主要用于对用户请求进行预处理和后处理,拥有一个典型的 处理链 .Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应.使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filt

  • Spring Boot项目实战之拦截器与过滤器

    一.拦截器与过滤器 在讲Spring boot之前,我们先了解一下过滤器和拦截器.这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的.在分析两者的区别之前,我们先理解一下AOP的概念,AOP不是一种具体的技术,而是一种编程思想.在面向对象编程的过程中,我们很容易通过继承.多态来解决纵向扩展. 但是对于横向的功能,比如,在所有的service方法中开启事务,或者统一记录日志等功能,面向对象的是无法解决的.所以AOP--面向切面编程其实是面向对象编程思想的一个补充.而我们今天讲的过滤器

  • spring boot设置过滤器、监听器及拦截器的方法

    前言 其实这篇文章算不上是springboot的东西,我们在spring普通项目中也是可以直接使用的 设置过滤器: 以前在普通项目中我们要在web.xml中进行filter的配置,但是只从servlet 3.0后,我们就可以在直接在项目中进行filter的设置,因为她提供了一个注解@WebFilter(在javax.servlet.annotation包下),使用这个注解我们就可以进行filter的设置了,同时也解决了我们使用springboot项目没有web.xml的尴尬,使用方法如下所示 @

  • 详谈springboot过滤器和拦截器的实现及区别

    前言 springmvc中有两种很普遍的AOP实现: 1.过滤器(Filter) 2.拦截器(Interceptor) 本篇面对的是一些刚接触springboot的人群 所以主要讲解filter和interceptor的简单实现和它们之间到底有什么区别 (一些复杂的功能我会之后发出文章,请记得关注) Filter的简单实现 字面意思:过滤器就是过滤的作用,在web开发中过滤一些我们指定的url 那么它能帮我们过滤什么呢? 那功能可就多了: 比如过拦截掉我们不需要的接口请求 修改请求(reques

  • SpringBoot实现拦截器、过滤器、监听器过程解析

    这篇文章主要介绍了SpringBoot实现拦截器.过滤器.监听器过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 过滤器 过滤器简介 过滤器的英文名称为 Filter, 是 Servlet 技术中最实用的技术.如同它的名字一样,过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作 Session 校验,判断用户权限,如果不符合设定条件,则会被拦截到特殊的地址或者基于特殊的响应. 过滤器的使用 首

  • spring boot实现过滤器和拦截器demo

    整理文档,搜刮出一个spring boot实现过滤器和拦截器demo ,稍微整理精简一下做下分享. 拦截器定义: @WebServlet public class ActionInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Ex

  • SpringBoot定义过滤器、监听器、拦截器的方法

    一.自定义过滤器 创建一个过滤器,实现javax.servlet.Filter接口,并重写其中的init.doFilter.destory方法. package com.example.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.Se

  • Spring Boot拦截器和过滤器实例解析

    这篇文章主要介绍了Spring Boot拦截器和过滤器实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.拦截器与过滤器 在讲Spring boot之前,我们先了解一下过滤器和拦截器.这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的.在分析两者的区别之前,我们先理解一下AOP的概念,AOP不是一种具体的技术,而是一种编程思想.在面向对象编程的过程中,我们很容易通过继承.多态来解决纵向扩展. 但是对于横向的功能,比如,在所

  • Spring拦截器和过滤器的区别在哪?

    一.概述 拦截器和过滤器 filter和拦截器的功能都是拦截,filter拦截的目标是servlet的执行,而拦截器拦截的是Spring MVC定义的概念,叫handler(常见的就是我们用RequestMapping定义出来的HandlerMethod).觉得它相似是因为Spring的handler就是DispatcherServlet使用的,而后者就是一个servlet.filter包围着dispatcherServlet,而它自己也想去执行一个目标handler,并在执行周围包裹着拦截器,

  • SSM项目中使用拦截器和过滤器的实现示例

    一.拦截器概述 Spring MVC 也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定 的功能,自定义的拦截器必须实现 HandlerInterceptor 接口 preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理.如果程序员决定该拦截器对请求进行拦截处理后还要调用其他 的拦截器,或者是业务处理器去进行处理,则返回 true:如果程序员决定不需要 再调用其他的组件去处理请求,则返回 false. postHandle(

  • Java拦截器和过滤器的区别分析

    一.过滤器(filter) 过滤器处于客户端与Web资源(Servlet.JSP.HTML)之间,客户端与Web资源之间的请求和响应都要通过过滤器进行过滤.举例:在过滤器中定义了禁止访问192.10.10.1这个地址,那么当客户端发出访问192.10.10.1的请求时,经过过滤器后,客户端得到的响应是出现该IP禁止访问的提示.在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑

  • spring boot拦截器的使用场景示例详解

    前言 在用户登陆之后,我们一般会把用户登陆的状态和相关信息进行存储,把对应的token返回到客户端进行存储,下次请求过来时,系统可以通过token拿到当前这个用户的相关信息,这是授权通常的作法,而有时一些业务里,你存储的用户信息不是全局的,可能只是某几个接口会用户某些信息,而你把它存储起来就不是很合理:并且一些隐私信息持久化到redis也不合理,这时就需要统一对这种接口的请求做一起处理了. 拦截器HandlerInterceptor 我们可以去实现这个HandlerInterceptor接口,它

  • Spring boot拦截器实现IP黑名单的完整步骤

    一·业务场景和需要实现的功能 以redis作为IP存储地址实现. 业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口. 实现功能:写一个拦截器拦截掉黑名单IP,额外增加一个接口,将ip地址添加到redis中,并且返回redis中当前全部ip 二·Springboot中定义一个拦截器 @Order(0) @Aspect @Component public class AopInterceptor { /** * 定义拦截器规则 */ @Pointcut("execution(*

  • spring boot拦截器注入不了java bean的原因

    一.如何实现拦截器 在Spring Boot项目中,拦截器经常被用来做登陆验证,日志记录等操作.拦截器是Spring提供的,所以可以将拦截器注成bean,由IOC容器来管理.实现拦截器的方式很简单,主要由以下两个步骤: 自定义拦截器类实现HandlerInterceptor接口 自定义WebMvc配置类实现WebMvcConfigurer接口,添加自定义拦截器类 简要实现代码如下: 自定义拦截器 LoginInterceptor: public class LoginInterceptor im

  • spring boot拦截器实现IP黑名单实例代码

    前言 最近一直在搞 Hexo+GithubPage 搭建个人博客,所以没怎么进行 SpringBoot 的学习.所以今天就将上次的"?秒防刷新"进行了一番修改.上次是采用注解加拦截器(@Aspect)来实现功能的.但是,如果需求是一个全局的拦截器对于大部分URL都进行拦截的话,自己一个个加显然是不可能的.而且上次的拦截器对于Controller的参数有所要求,在实际他人引用总是显得不方便.所以,这次使用了继承HandlerInterceptor来实现拦截器. 功能需求 对于项目中某类U

  • Spring Boot拦截器实现步骤及测试实例

    第一步,定义拦截器: package com.zl.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public

  • 浅谈springMVC拦截器和过滤器总结

    拦截器: 用来对访问的url进行拦截处理 用处: 权限验证,乱码设置等 spring-mvc.xml文件中的配置: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" x

随机推荐