filter和interceptor的区别

简介: filter和interceptor的区别

前言

最近在面试的时候,被问到了这个问题,觉得答得不是很好,在此进行整理和记录,供自己学习,也希望能帮助到大家。

什么是Filter

在java的javax.servlet下有一个接口Filter。任何实现了Filter接口的类都可以称之为filter。Filter的主要用途是设置字符集、控制权限、控制转向等等。在使用filter的过程中,如果是传统的web项目,带有web.xml文件这种。我们需要在xml里面进行配置。比如下面这样。

    <filter>
        <description>字符集过滤器</description>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <description>字符集编码</description>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

这种使用方式直接将我们的请求和响应的字符集全部改为utf-8的形式。

如果是在spingboot这种项目中使用,我们定义好自己的filter类之后,需要使用filterregisterbean将filter进行注入。

Filter随着项目的启动而启动,只初始化一次,随着web项目的停止而销毁。

Filter主要用于对用户请求的预处理和程序返回response的后处理。可以在请求到达servlet之前进行request的处理或者添加头和一些其他数据。或者在reponse到达之前,修改response的头和数据。

filter中总共有三个方法。
void init(FilterConfig config):用于完成Filter的初始化。
void destory():用于filter销毁前,完成资源的回收。
void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):该方法是filter的核心过滤方法。通过request进行请求处理,然后调用chain.doFilter。调用完之后,可以通过response进行响应处理。

拦截器

拦截器是aop的一种实现方案,是aop思想的体现。在我们调用方法之前,调用拦截器的一个方法或者在调用方法之后,调用拦截器的一个方法。

SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

(1)preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式调用,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为true时就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法。

(2)postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion方法都只能是在当前所属的Interceptor的preHandle方法的返回值为true时才能被调用。postHandle方法,顾名思义就是在当前请求进行处理之后,也就是Controller方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说先声明的Interceptor的postHandle方法反而会后执行。

(3)afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
执行的顺序如下:

需要注意的点就是当preHandler为true的时候,postHandler才能执行。当为false的时候,afterCompletion仍然会执行。

filter和interceptor的区别总结

1、filter接口在javax.servlet包下面。inteceptor定义在org.springframework.web.servlet中。
2、filter是servlet规定的,interceptor即可用于web程序,也可用于application中。
3、filter是servlet容器支持的,interceptor是spring框架支持的。
4、filter通过dochain放行,interceptor通过prehandler放行。
5、filter只在方法前后执行,interceptor粒度更细,可以深入到方法前后,异常抛出前后。

相关文章
|
弹性计算 JavaScript Linux
ElasticSearch备份与恢复-elasticdump工具
ElasticSearch备份与恢复-elasticdump工具
|
消息中间件 RocketMQ
rocketMq错误日志所在位置
rocketMq错误日志所在位置
466 0
|
10月前
|
XML 人工智能 监控
SpringBoot实战:七种统计方法耗时的实现方式
在Spring Boot开发中,统计方法执行时间是性能优化的重要手段。本文介绍了七种实现方法耗时统计的技巧,包括手动使用StopWatch、AOP全局监控、自定义注解+切面、拦截器、Filter、Actuator+Micrometer集成以及事件监听等方式。每种方法适用于不同场景,开发者可根据需求选择合适的方案,从而更高效地定位性能瓶颈并提升系统响应速度。
1292 5
|
Linux 虚拟化 Docker
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
|
缓存 编解码 JavaScript
理解打包好的vue项目结构dist包
理解打包好的vue项目结构dist包
742 3
|
存储 前端开发 Java
如何使用 Spring 上传文件:全面指南
如何使用 Spring 上传文件:全面指南
1584 1
|
Java
Java aop 如何获取方法的参数体
【8月更文挑战第12天】Java aop 如何获取方法的参数体
757 2
|
数据采集 传感器 边缘计算
不同类型的工业网关有何区别?
【8月更文挑战第8天】工业网关关键于工业自动化中的连接与数据转换,主要分为协议转换网关、数据采集网关及边缘计算网关。协议转换网关解决不同工业协议间的兼容性问题;数据采集网关负责收集并初步处理多类设备数据;边缘计算网关则在此基础上增加了现场数据处理能力,减轻云端负担。选型时需依据具体需求与系统结构。
580 2
|
Docker 容器
Dockerfile 与 Docker Compose区别
用途: Dockerfile 用于定义单个容器的构建过程。它包含了一系列指令,每个指令都代表容器构建过程中的一个步骤。这些步骤包括从基础镜像中构建、安装依赖、拷贝文件、设置环境变量等操作。 语法: Dockerfile 是一个文本文件,其中包含一系列 Docker 指令。每个指令都会生成一个新的镜像层。常见的指令包括 FROM(指定基础镜像)、RUN(执行命令)、COPY(拷贝文件)、EXPOSE(暴露端口)、CMD(设置容器启动时执行的命令)等。 灵活性: Dockerfile 提供了灵活的方式来定义容器构建过程,允许用户精确地控制容器的组件和配置。 使用场景: Dockerfile 适用于
599 1
|
缓存 算法 安全
[译] OpenSSL 3.0.0 设计
本文翻译 OpenSSL 官网文档:https://www.openssl.org/docs/OpenSSL300Design.htmlTongsuo-8.4.0 是基于 OpenSSL-3.0.3 开发,所以本文对 Tongsuo 开发者同样适用,内容丰富,值得一读!介绍本文概述了 OpenSSL 3.0 的设计,这是在 1.1.1 版本之后的 OpenSSL 的下一个版本。假设读者熟悉名为 &
552 0
[译] OpenSSL 3.0.0 设计