• 拦截器与过滤器的区别(九)


    前言

    相同之处:

    【Spring的拦截器】与【Servlet的Filter】有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。

    不同之处:

    • 使用范围不同:【Filter是Servlet规范固定的,只能用于Web程序中】,而【拦截器既可以用户Web程序,也可以用于Application、Swing程序中】。
    • 规范不同:Filter是在Servlet规范中定义的,是【Servlet容器支持】的,而拦截器是在Spring容器内的,是【Spring框架支持】的。
    •  使用的资源不同:同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里得任何资源、对象,例如Service对象、数据源、事务管理等,通过Ioc注入道拦截器即可。而Filter则不能。
    • 深度不同:【Filter在只在Servlet启动前后起作用。而拦截器能够深入到方法前后、异常抛出前后等】,因此拦截器的使用弹性更大一些,所以在使用Spring架构的程序中,要优先使用拦截器。

    一、二者理解

    过滤器(Filter)

    过滤器,是在java web中将你传入的request、response提前过滤掉一些信息,或者提前设置一些参数。然后再传入Servlet或Struts2的 action进行业务逻辑处理。比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入Servlet或Struts2的action前统一设置字符集,或者去除掉一些非法字符。

    拦截器(Interceptor)

    拦截器,是面向切面编程(AOP,Aspect Oriented Program)的。就是在你的Service或者一个方法前调用一个方法,或者在方法后调用一个方法。比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

    通俗理解:
    (1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)
    (2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预它,通过验证的少点,顺便干点别的东西)

    二、拦截器与过滤器的区别

    区别:

    ①:拦截器是基于java的反射机制的,而过滤器是基于函数的回调。
    ②:拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
    ③:拦截器只对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
    ④:拦截器可以访问action上下文、值、栈里面的对象,而过滤器不可以。
    ⑤:在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    ⑥:拦截器可以获取IOC容器中的各个bean,而过滤器不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

    三、拦截器与过滤器的触发时机

    拦截器与过滤器触发时机不一样

    过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

    过滤器包裹servlet,servlet包裹住拦截器。

    四、使用场景

    4.1拦截器使用场景

    SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。

    1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
    2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
    3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
    4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
    5、OpenSessionInView:如hibernate,在进入处理器打开Session,在完成后关闭Session。

    4.2何时使用拦截器?何时使用过滤器?

    如果是非spring项目,那么拦截器不能用,只能使用过滤器。

    如果是处理controller前后,既可以使用拦截器也可以使用过滤器。

    如果是处理dispaterServlet前后,只能使用过滤器。

    五、图解

    1、过滤器和拦截器触发时机不一样,过滤器是在【请求进入容器后,但请求进入servlet之前】进行预处理的。请求结束返回也是,是【在servlet处理完后,返回给前端之前】。

    在这里插入图片描述

    2、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。

    过滤器拦截器运行先后步骤:


    在这里插入图片描述

    其中第2步,SpringMVC的机制是由DispaterServlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。

    3、过滤器的实现基于回调函数。而【拦截器(代理模式)的实现基于反射】,代理分静态代理和动态代理,动态代理是拦截器的简单实现。


    在这里插入图片描述

    六、部分代码

    6.1、过滤器(Filter)

    首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题:

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>/*</servlet-name>
    </filter-mapping>


    配置这个地方的目的,是让所有的请求都需要进行字符编码的设置,下面来介绍一下Filter。

    (1)过滤器(Filter):它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

    6.2、拦截器(Interceptor)

    拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签,具体配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

    (2)拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。

    6.3总结

    对于上述过滤器和拦截器的测试,可以得到如下结论:
    (1)、Filter需要在web.xml中配置,依赖于Servlet;
    (2)、Interceptor需要在SpringMVC中配置,依赖于框架;
    (3)、Filter的执行顺序在Interceptor之前,具体的流程见下图;

    è¿éåå¾çæè¿°

    (4)、两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

    参看链接:

    https://blog.csdn.net/weixin_44502804/article/details/93139550

    https://blog.csdn.net/longzhongxiaoniao/article/details/85727725

    https://www.iteye.com/blog/uule-2442198

    如果错过太阳时你流了泪,那你也要错过群星了。
    在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
    不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。
  • 相关阅读:
    Longest Palindromic Substring问题
    twosum问题
    longest substring问题
    特殊的ARP
    【转】人肉搜索技巧
    ARP攻击
    Linux kali安装及常用命令收集
    【转】ICMP协议
    SpringBoot集成Mybatis-XML方式通用Mapper
    springMVC的controller中insert()多次,记优惠券被多次领取
  • 原文地址:https://www.cnblogs.com/szrs/p/14404357.html
Copyright © 2020-2023  润新知