有什么作用?
过滤器 和 拦截器 都可以在请求到达目标资源之前或响应返回客户端之前执行某些操作。
过滤器 和 拦截器 都支持链式调用,即可以配置多个过滤器或拦截器按顺序执行。每个过滤器或拦截器都可以决定是否将请求传递给下一个处理单元。
过滤器 和 拦截器 都有初始化、使用和销毁的生命周期。
过滤器 和 拦截器 都可以用于实现跨切面编程(AOP),即在不修改业务逻辑代码的情况下,添加额外的功能。
. . . . . .
过滤器和拦截器在功能方面很相似,但也有以下不同:
-
过滤器出现在SpringMVC框架出现之前,而SpringMVC在成为主流框架之后,拦截器才得以广泛应用
-
过滤器和拦截器 底层实现方式大不相同,
过滤器
是基于函数回调的,拦截器
则是基于Java的反射机制(动态代理)实现的。 -
过滤器 和 拦截器的触发时机也不同,在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
......
过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
快速使用
现在咱直接看到使用部分:
controller代码样例
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/hello")
public String test() {
return "hello world";
}
}
过滤器
-
第一步:创建自定义过滤器类
创建
filter
包 ,在该包下创建MyFilter
类(注意导入的包)实现Filter接口,重写方法
-
第二步:添加配置注解
在
MyFilter
上添加@WebFilter(urlPatterns = "/*")
表示对目标请求的过滤,此处表示过滤所有请求在启动类上加上
@ServletComponentScan(basePackages = "com.demo.meetingdemo.filter")
注解,扫描自己配置的过滤器的包
-
第三步:实现过滤逻辑
@WebFilter(urlPatterns = "/*") public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("MyFilter初始化了..."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpSession session = request.getSession(); Integer count = (Integer)session.getAttribute("count"); if ( count == null) { session.setAttribute("count", 0); System.out.println( "第一次访问"); }else { System.out.println( "访问次数:" + ++count); session.setAttribute("count", count); } filterChain.doFilter(request, servletResponse); } @Override public void destroy() { System.out.println("MyFilter销毁了..."); } }
拦截器
-
第一步:创建自定义拦截器类
创建
interceptor
包,在包下创建MyInterceptor
类,实现HandlerInterceptor
接口,重写preHandle
方法
-
第二步:创建配置类
@Configuration public class InterceptoConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { MyInterceptor myInterceptor = new MyInterceptor(); registry.addInterceptor(myInterceptor).addPathPatterns("/**"); } }
-
第三步:实现拦截逻辑
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); Integer count = (Integer)session.getAttribute("count"); //获取访问ip System.out.println( "ip:" + request.getRemoteAddr()); if ( count == null) { session.setAttribute("count", 1); System.out.println( "访问次数:" + 1); }else { System.out.println( "访问次数:" + count); session.setAttribute("count", ++count); } System.out.println("MyInterceptor 拦截器执行了..."); // return false; return true; } }