过滤器和拦截器区别
过滤器(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