• 过滤器和拦截器


     参考文章:https://blog.csdn.net/zxd1435513775/article/details/80556034

    拦截器过滤器监听器学习小地址:https://www.jianshu.com/p/365a65252bb9https://www.jianshu.com/p/f216fe347f36https://www.jianshu.com/p/9667cea376e5

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

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

    在ssm框架配置上的区别:

    (1)、Filter需要在web.xml中配置,依赖于Servlet;
    (2)、Interceptor需要在SpringMVC中配置,依赖于框架;
    (3)、Filter的执行顺序在Interceptor之前,具体的流程见下图;

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

    图一:

    出来时依然经过过滤器,但是过滤器不起作用了(网上一个人说的,不确定是否正确)

    图二:

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

    • 如果是非spring项目,那么拦截器不能用,只能使用过滤器。
    • 如果是处理controller前后,既可以使用拦截器也可以使用过滤器。
    • 如果是处理dispaterServlet前后,只能使用过滤器

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

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

    我理解拦截器就是拦截了,进行一些处理,如果符合条件则通过,否则不通过,比如项目组的验证签名,通过拦截器来实现

    springboot如何开发拦截器:https://www.cnblogs.com/paddix/p/8365558.html

    编写拦截器实现类,此类必须实现接口   HandlerInterceptor,然后重写里面需要的三个比较常用的方法,实现自己的业务逻辑代码;

    说明:

    1、preHandle  方法会在请求处理之前进行调用(Controller方法调用之前)

    2、postHandle  请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)

    3、afterCompletion  在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)

    注意:其中LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/index");中的addPathterns中的参数是所要拦截的路径,excludePathPatterns中的参数是:不拦截的路径

    package com.leecx.interceptors.interceptor;
    
    
    import com.leecx.pojo.LeeJSONResult;
    import com.leecx.utils.JsonUtils;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    
    public class OneInterceptor implements HandlerInterceptor{
    
        /**
         * 在请求处理之前进行调用(Controller方法调用之前)
         */
        @Override
        public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
    
            System.out.println("=====================");
            if (true) {
                returnErrorResponse(httpServletResponse, LeeJSONResult.errorMsg("被one拦截..."));
            }
    
            System.out.println("被one拦截...");
    
            return false;
        }
    
        /**
         * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
         */
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
        }
    
        /**
         * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
         */
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    
        }
    
        public void returnErrorResponse(HttpServletResponse response, LeeJSONResult result) throws IOException, UnsupportedEncodingException {
            OutputStream out = null;
            try{
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/json");
                out = response.getOutputStream();
                out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
                out.flush();
            } finally{
                if(out!=null){
                    out.close();
                }
            }
        }
    }

     过滤器的编写:

    要实现Filter,重写里面的三个方法init,doFilter,destroy

    写一个过滤器。过滤实现在doFilter方法里面。chain.doFilter(request, response)  表示过滤通过,能够往下执行。所以过滤操作要写在chain.doFilter(request, response) 前面,作一些条件判断,如果不符合条件,则不执行chain.doFilter(request, response)


    过滤器的配置以及多个过滤器执行顺序:https://www.cnblogs.com/ideal-20/p/11496091.htmlhttps://www.jianshu.com/p/365a65252bb9

    构造器:创建Filter实例是调用,Filter实例服务器一旦启动就会被创建

    init():实例创建后马上被调用,用来对Filter做一些初始化的操作

    doFilter():Filter的主要方法,用来完成过滤器主要功能的方法,每次访问目标资源时都会调用。

    destroy():服务器停止时调用,用来释放资源。

     

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

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

    FilterConfig接口 :

  • 相关阅读:
    C#字符串转换为数字的4种方法
    Linq to SQL Xml Based
    Code Snippets in Visual Studio 2010
    cygwin 压缩
    Cygwin安装Gitolite3
    ubuntu下如何用命令行运行deb安装包
    iconv bom
    __stdcall型dll转lib
    cygwin install lua modules
    luacom cygwin
  • 原文地址:https://www.cnblogs.com/cherishforchen/p/11348147.html
Copyright © 2020-2023  润新知