Java中的拦截器和过滤器有什么区别

简介: 过滤器Filter基于Servlet实现,过滤器的主要应用场景是对字符编码、跨域等问题进行过滤。Servlet的工作原理是拦截配置好的客户端请求,然后对Request和Response进行处理。Filter过滤器随着web应用的启动而启动,只初始化一次。Filter的使用比较简单,继承Filter 接口,实现对应的init、doFilter以及destroy方法即可。

本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看


(一)什么是过滤器


过滤器Filter基于Servlet实现,过滤器的主要应用场景是对字符编码、跨域等问题进行过滤。Servlet的工作原理是拦截配置好的客户端请求,然后对Request和Response进行处理。Filter过滤器随着web应用的启动而启动,只初始化一次。

Filter的使用比较简单,继承Filter 接口,实现对应的init、doFilter以及destroy方法即可。


1、init:在容器启动时调用初始化方法,只会初始化一次


网络异常,图片无法展示
|

2、doFilter:每次请求都会调用doFilter方法,通过FilterChain 调用后续的方法


网络异常,图片无法展示
|

3、destroy:当容器销毁时,执行destory方法,只会被调用一次。


网络异常,图片无法展示
|

下面是详细的代码编写方式:


publicclassMyFilterimplementsFilter {
@Overridepublicvoidinit(FilterConfigfilterConfig) throwsServletException {
System.out.println("初始化拦截器");
    }
@OverridepublicvoiddoFilter(ServletRequestrequest, ServletResponseresponse, FilterChainchain) throwsIOException, ServletException {
//做一些处理chain.doFilter(request,response);
    }
@Overridepublicvoiddestroy() {
System.out.println("销毁拦截器");
    }
}

(二)什么是拦截器


拦截器是SpringMVC中实现的一种基于Java反射(动态代理)机制的方法增强工具,拦截器的实现是继承HandlerInterceptor 接口,并实现接口的preHandle、postHandle和afterCompletion方法。


1、preHandle:请求方法前置拦截,该方法会在Controller处理之前进行调用,Spring中可以有多个Interceptor,这些拦截器会按照设定的Order顺序调用,当有一个拦截器在preHandle中返回false的时候,请求就会终止。


2、postHandle:preHandle返回结果为true时,在Controller方法执行之后,视图渲染之前被调用


3、afterCompletion:在preHandle返回ture,并且整个请求结束之后,执行该方法。

具体的代码实现如下,首先编写一个拦截器:


@ComponentpublicclassUserInterceptorimplementsHandlerInterceptor {
@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler) throwsException {
System.out.println("preHandle");
StringuserName=request.getParameter("userName");
Stringpassword=request.getParameter("password");
if (userName==null||password==null){
response.setStatus(500);
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print("参数缺失");
returnfalse;
        }
//进行用户校验if (userName.equals("admin")&&password.equals("admin")){
returntrue;
        }else {
response.setStatus(500);
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print("用户名或密码错误");
returnfalse;
        }
    }
@OverridepublicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, ModelAndViewmodelAndView) throwsException {
System.out.println("postHandle");
    }
@OverridepublicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex) throwsException {
System.out.println("afterCompletion");
    }
}

编写完拦截器之后,通过一个配置类设置拦截器,并且可以通过

addPathPatternsexcludePathPatterns执行哪些请求需要被拦截,哪些不需要被拦截。

@ConfigurationpublicclassMvcConfigimplementsWebMvcConfigurer {
@AutowiredprivateUserInterceptoruserInterceptor;
@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry) {
registry.addInterceptor(userInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/error");
    }
}

(三)拦截器与过滤器的区别


相同点


1、拦截器与过滤器都是体现了AOP的思想,对方法实现增强,都可以拦截请求方法。

2、拦截器和过滤器都可以通过Order注解设定执行顺序


不同点


1、过滤器属于Servlet级别,拦截器属于Spring级别Filter是在javax.servlet包中定义的,要依赖于网络容器,因此只能在web项目中使用。


Interceptor是SpringMVC中实现的,归根揭底拦截器是一个Spring组件,由Spring容器进行管理。


2、过滤器和拦截器的执行顺序不同


下面通过一张图展示Filter和Interceprtor的执行顺序


网络异常,图片无法展示
|


首先当一个请求进入Servlet之前,过滤器的doFilter方法进行过滤,

进入Servlet容器之后,执行Controller方法之前,拦截器的preHandle方法进行拦截,

执行Controller方法之后,视图渲染之前,拦截器的postHandle方法进行拦截,

请求结束之后,执行拦截器的postHandle方法。


3、过滤器基于函数回调方式实现,拦截器基于Java反射机制实现


(四)总结


实际开发中,拦截器的应用场景会比过滤器要更多,下面是拦截器和过滤器的主要应用场景


拦截器的应用场景:权限控制,日志打印,参数校验


过滤器的应用场景:跨域问题解决,编码转换


我翻了一下历史项目的代码,拦截器在用户权限校验场景下使用会比较多,由于一般是前后端分离项目,过滤器的使用场景就会少很多。


网络异常,图片无法展示
|

拦截器和过滤器算是比较常用的了,但是还是得注意两者的差距,我是鱼仔,我们下期再见!



相关文章
|
13天前
|
监控 Java 数据管理
java会话跟踪和拦截器过滤器
本文介绍了Web开发中的会话跟踪技术——Cookie与Session,以及过滤器(Filter)和监听器(Listener)的概念和应用。Cookie通过在客户端记录信息来识别用户,而Session则在服务器端保存用户状态。过滤器用于拦截和处理请求及响应,监听器则监控域对象的状态变化。文章详细解释了这些技术的实现方式、应用场景和主要方法,帮助开发者更好地理解和使用这些工具。
30 1
|
16天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
24天前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
1月前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
23 1
|
1月前
|
Java 编译器 C语言
【一步一步了解Java系列】:探索Java基本类型与C语言的区别
【一步一步了解Java系列】:探索Java基本类型与C语言的区别
42 2
|
1月前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
35 1
|
1月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
76 1
|
27天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
29天前
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
68 0
|
10天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。