过滤器和拦截器的区别?

本文详细比较了过滤器和拦截器在Web开发中的概念、实现方式、依赖关系、执行顺序以及作用范围,并探讨了它们在注入Bean时的不同。重点介绍了如何在SpringMVC中管理和配置这两种组件。
摘要由CSDN通过智能技术生成

过滤器和拦截器在我们的开发过程中,使用到的是相当多的。下面就从实现方式,依赖关系,执行顺序,作用范围,注入Bean几个方面来说说它们的不同。

过滤器和拦截器的概念

过滤器(Filter)是拦截请求和响应的web组件Web项目中通常用它来处理中文参数乱码问题。

拦截器(Interceptor)是一种用于在请求进入Controller之前对其进行预处理,或者在请求离开Controller之后对其进行后处理的组件。拦截器可以用来记录请求的日志信息,处理异常,检查用户的登录状态,等等。

实现方式

过滤器(Filter)的实现方式通常是实现 javax.servlet.Filter 接口,并重写 doFilter 方法。下面是一个简单的例子:

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {

    private ServletContext servletContext;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.servletContext = filterConfig.getServletContext();
    }

    @Override
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 在这里可以做一些预处理,例如读取请求参数,修改请求参数,等等

        // 调用下一个过滤器或Controller
        chain.doFilter(request, response);

        // 在这里可以做一些后处理,例如写入响应体,等等
    }
}

在这个例子中,我们实现了 javax.servlet.Filter 接口,并实现了 doFilter 方法。在 doFilter 方法中,我们可以做一些预处理和后处理,例如读取请求参数,写入响应体,等等。注意,我们需要调用 chain.proceed() 方法来继续执行后续的处理步骤。

拦截器(Interceptor)的实现方式通常是实现HandlerInterceptor接口,下面是一个简单的例子:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 预处理阶段,可以在请求处理之前执行,比如权限校验、日志记录等
        System.out.println("MyInterceptor: Pre-handle request");

        // 如果返回false,请求将被中断,后续的Controller不会执行
        // 这里返回true表示允许请求继续执行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 后处理阶段,在请求处理之后,视图渲染之前执行
        System.out.println("MyInterceptor: Post-handle request");
        
        // 可以在此处修改模型数据或视图
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 整个请求完成后执行,主要用于资源清理、记录请求耗时等工作
        System.out.println("MyInterceptor: After completion");

        // 如果在preHandle阶段抛出了异常,ex参数会携带异常信息
    }
}

依赖关系

过滤器和拦截器之间存在一种依赖关系。一般来说,过滤器会在拦截器之前执行,也就是说,请求先经过过滤器的处理,然后再经过拦截器的处理。

这种依赖关系主要是因为过滤器和拦截器的功能不同造成的。过滤器主要用于在请求进入容器之前对其进行预处理,例如读取请求参数,修改请求参数,等等。而拦截器主要用于在请求进入Controller之前对其进行预处理,例如记录日志信息,处理异常,检查用户登录状态,等等。

另外,过滤器和拦截器的执行顺序也是可以配置的。在Spring MVC中,可以通过在web.xml文件中配置过滤器的执行顺序,来改变过滤器的执行顺序。同样,也可以通过在application-context.xml文件中配置拦截器的执行顺序,来改变拦截器的执行顺序。

执行顺序

过滤器和拦截器的执行顺序是可以配置的。在Spring MVC中,可以通过在web.xml文件中配置过滤器的执行顺序,来改变过滤器的执行顺序。同样,也可以通过在application-context.xml文件中配置拦截器的执行顺序,来改变拦截器的执行顺序。

在Spring MVC中,默认情况下,过滤器的执行顺序是按照它们在web.xml文件中配置的顺序执行的。例如,如果有两个过滤器A和B,A在B前面,那么A将会先执行,然后才是B。

同样,拦截器的执行顺序也是按照它们在application-context.xml文件中配置的顺序执行的。例如,如果有两个拦截器C和D,C在D前面,那么C将会先执行,然后才是D。

当然,这只是一个默认的执行顺序,实际上,我们完全可以根据我们的需求来调整过滤器和拦截器的执行顺序。

作用范围

过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。

拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。

一般来说,过滤器的作用范围更广,可以覆盖整个请求处理过程,包括请求的输入和输出。而拦截器的作用范围相对较小,只能覆盖请求的输入,即请求的预处理。

具体来说,过滤器可以用来读取和修改请求的参数,例如读取请求的URL参数,读取请求的POST参数,修改请求的POST参数,等等。过滤器还可以用来修改请求的响应,例如修改响应的编码,修改响应的头部,等等。

相比之下,拦截器的作用范围要小得多。拦截器主要用于在请求进入Controller之前对其进行预处理,例如记录日志信息,处理异常,检查用户登录状态,等等。拦截器不能修改请求的输入,也不能修改请求的输出。

注入Bean

如果我们需要在过滤器和拦截器中使用到业务逻辑,通常会注入一些Service来帮助我们完成这些任务。然而,这两种方式的注入方式有所不同。

过滤器中注入service,一切正常!

拦截器中注入service,注入的serviceNull,原因:这是因为加载顺序导致的问题,拦截器加载的时间点在springcontext之前,而Bean又是由spring进行管理。解决方案也很简单,我们在注册拦截器之前,先将Interceptor 手动进行注入。

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值