Fork me on GitHub

过滤器和拦截器区别

过滤器(Filter)

简介

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

代码

import org.springframework.stereotype.Component;
import javax.servlet.*;
import java.io.IOException;

/**
 * @program:FoundationStudy
 * @Author: zhuyang
 * @Date: 2022/02/06/20:50
 * @Description: 自定义我的过滤器
 */
@Component
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("-------过滤器初始化init方法执行-----");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-------过滤器doFilter方法前执行-----");
        filterChain.doFilter(servletRequest, servletResponse);
        //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后
        System.out.println("-------过滤器doFilter方法后执行-----");
    }

    @Override
    public void destroy() {
        System.out.println("-------过滤器destroy方法执行-----");
    }
}

拦截器

简介

它依赖于web框架,在SpringBoot中就是依赖于SpringMVC框架,在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作, 拦截器可以对静态资源的请求进行拦截处理。

代码

import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @program:FoundationStudy
 * @Author: zhuyang
 * @Date: 2022/02/06/20:53
 * @Description: 自定义我的拦截器
 * 它依赖于web框架,在SpringBoot中就是依赖于SpringMVC框架。
 * 在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,
 * 就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,
 * 比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作, 拦截器可以对静态资源的请求进行拦截处理。
 */
@Component
public class MyInterceptor implements HandlerInterceptor {


    /**
     * @Description:
     * @Author: zhuyang
     * @Date:  2022-02-06
     * @Param:
     * @return:
     * 在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
     * 即在HandlerMapping执行之后,HandlerAdapter执行之前进行执行
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("--------自定义拦截器preHandle方法执行----------");
        return true;
    }

    /**
     * @Description:
     * @Author: zhuyang
     * @Date:  2022-02-06
     * @Param:
     * @return:
     * 在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,
     * 但未进行页面渲染),
     * 有机会修改ModelAndView 生产环境中基本不使用
     **/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("--------自定义拦截器postHandle方法执行----------");
    }

    /**
     * @Description:
     * @Author: zhuyang
     * @Date:  2022-02-06
     * @Param:
     * @return:
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。
     **/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("--------自定义拦截器afterCompletion方法执行----------");
    }
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Resource
    private MyInterceptor myInterceptor;
	/**
     * @Description: 添加过滤器
     * @Author: zhuyang
     * @Date:  2022-02-06
     * @Param:
     * @return:
     **/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加过滤器,可添加多个
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }

}

业务逻辑代码

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @description:
 * @projectName:FoundationStudy
 * @see:com.yxkj.springbootdemo.controller
 * @author:zhuyang
 * @createTime:2021/10/12 22:47
 * @version:1.0
 */
@Controller
@Api(tags = "测试")
@RequestMapping("/testController")
public class TestController {


    @ApiOperation("测试")
    @RequestMapping(value = "/sayHello",method = RequestMethod.GET)
    @ResponseBody //这里必须要加上该注解,不知为啥,等下查明原因
    public Object sayHello(String name){
        System.out.println("---------------------方法执行----------------");
        return "hello " + name;
    }

}

测试结果

-------过滤器初始化init方法执行-----
-------过滤器doFilter方法前执行-----
--------自定义拦截器preHandle方法执行----------
---------------------方法执行----------------
--------自定义拦截器postHandle方法执行----------
--------自定义拦截器afterCompletion方法执行----------
-------过滤器doFilter方法后执行-----

过滤器和拦截器区别

①:过滤器会在Filter初始化和销毁时调用;
②:过滤器Filter依赖于Servlet,拦截器Intercepto依赖于框架;
③:拦截器(Interceptor)是基于Java的反射机制(AOP思想),而过滤器(Filter)是基于函数回调。
④:两者在执行顺序上也不同。
https://blog.csdn.net/zhibo_lv/article/details/81875705

Gitee地址

https://gitee.com/zhuayng/foundation-study/tree/develop/SpringBootDemo

posted @ 2022-02-06 20:54  晨度  阅读(78)  评论(0编辑  收藏  举报