过滤器、拦截器与监听器

1.过滤器

依赖于servlet容器,实现基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操作,便于代码重用,不必每个servlet中进行冗余操作。

Java中的Filter并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest。根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。在响应到达客户端之前,拦截HttpServletResponse。根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。

Filter随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。
1.启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
2.每一次请求时都只调用方法doFilter()进行处理;
3.停止服务器时调用destroy()方法,销毁实例。

过滤器处理链过程:
浏览器发出的请求先递交给第一个filter进行过滤,符合规则则放行,递交给filter链中的下一个过滤器进行过滤。过滤器在链中的顺序与它在web.xml中配置的顺序有关,配置在前的则位于链的前端。当请求通过了链中所有过滤器后就可以访问资源文件了,如果不能通过,则可能在中间某个过滤器中被处理掉。web.xml中配置过滤器,这里要谨记一条原则:监听器>过滤器>servlet
在doFilter()方法中,chain.doFilter()前一般是对request执行的过滤操作,chain.doFilter后代码一般是对response执行的操作。

2.拦截器

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,拦截器可以调用IOC容器中的各种依赖,而过滤器不能,因此可以使用Spring的依赖注入进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。

spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式。一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring mvc的HanlderInterceptor, 复杂的,比如缓存,需要高度自定义的就用spring aop。一般来说service层更多用spring aop,controller层有必要用到request和response的时候,可以用拦截器。

spring mvc中的Interceptor拦截请求是通过HandlerInterceptor来实现的。所以HandlerInteceptor拦截器只有在Spring Web MVC环境下才能使用。在SpringMVC中定义一个拦截器主要有两种方式,第一种方式是要实现Spring的HandlerInterceptor接口,或者是其它实现了HandlerInterceptor接口的类,比如HandlerInterceptorAdapter。第二种方式是实现WebRequestInterceptor接口,或者其它实现了WebRequestInterceptor的类。

HandlerInterceptor接口定义方法preHandle, postHandle, 和afterCompletion:
preHandle(进入 Handler方法之前执行):预处理回调方法,实现处理器的预处理(如登录检查),返回值:true表示继续流程(如调用下一个拦截器或处理器),false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应。
postHandle(进入handler方法之后,返回modelAndView之前):后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion(执行Handler完成执行此方法):整个请求处理完毕回调方法,即在视图渲染完毕时回调。该方法也是需要当前对应的Interceptor 的preHandle方法的返回值为true时才会执行。这个方法的主要作用是用于进行资源清理工作的,如性能监控中我们可以在此记录结束时间并输出消耗时间。

3、监听器

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。

监听器原理
监听原理
1、存在事件源
2、提供监听器
3、为事件源注册监听器
4、操作事件源,产生事件对象,将事件对象传递给监听器,并且执行监听器相应监听方法

Servlet监听器
(不需要配置,但是监听器仍需要进行注册)
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSession 和 ServletRequest 这三个域对象。

Servlet监听器分为三大类
1、数据域对象创建和销毁监听器
2、数据域对象和属性变更监听器
3、绑定到 HttpSession 域中的某个对象的状态的事件监听器

拦截器和过滤器的区别
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调。
2.拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3.拦截器只能对Controller请求起作用,而过滤器则可以对几乎所有的请求起作用。
4.拦截器可以访问Controller上下文、值栈里的对象,而过滤器不能访问。
5.在Controller的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6.拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。

首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);
过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;
Action处理完成返回后,拦截器还可以做其他过程,再向上返回到过滤器的后续操作。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
拦截器过滤器监听器是在软件开发中常用的三种组件,用于对请求进行干预、选择和获取事件细节。它们的区别如下[^1][^2]: 1. 拦截器(Interceptor): 拦截器用于在请求进行中干预其进展,并可以控制是否终止请求的执行。拦截器可以在请求前、请求后或请求完成后执行特定的操作,例如记录日志、权限验证等。 2. 过滤器(Filter): 过滤器用于从一堆东西中选择符合特定要求的内容。它可以定义一些规则或条件,根据这些规则或条件来过滤出符合要求的内容。过滤器通常用于对请求进行预处理或后处理,例如请求参数的校验、字符编码的转换等。 3. 监听器(Listener): 监听器用于获取事件发生的细节,而不对事件的执行过程进行干预。当特定事件发生时,监听器可以捕获该事件并执行相应的操作。监听器通常用于记录日志、统计数据等。 示例代码如下: ```java // 拦截器示例 public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求前执行的操作 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求后执行的操作 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在请求完成后执行的操作 } } // 过滤器示例 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 过滤器初始化操作 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤器处理请求的操作 chain.doFilter(request, response); } @Override public void destroy() { // 过滤器销毁操作 } } // 监听器示例 public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 监听器初始化操作 } @Override public void contextDestroyed(ServletContextEvent sce) { // 监听器销毁操作 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辞暮尔尔-烟火年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值