过滤器和拦截器的区别


一、拦截器和过滤器的区别

1、过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

2、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。

3、过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射

4、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

5、Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。

6、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。
在这里插入图片描述
最简单明了的区别:
1.过滤器可以修改request,而拦截器不能
2.过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境
3.拦截器可以调用IOC容器中的各种依赖,而过滤器不能
4.过滤器只能在请求的前后使用,而拦截器可以详细到每个方法
调用方法流程如下:
在这里插入图片描述

1、过滤器

1、实现方式

1.使用spring boot提供的FilterRegistrationBean注册Filter
定义Filter:

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

注册Filter:

@Slf4j
@Order(1)
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("-----------------------MyFilter");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

2.使用原生servlet注解定义Filter

@WebFilter(filterName = "LoginFilter" ,urlPatterns = "/*")
@Slf4j
@Order(2)
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("进入过滤器init");
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("进入过滤器"+servletRequest.getRemoteAddr()+"|"+servletRequest.getRemoteHost()+"|"+servletRequest.getLocalPort()+"|"+servletRequest.getServerPort()
        );
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("进入过滤器destroy");
        Filter.super.destroy();
    }

这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式,过滤器名称等。这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在启动类中加另外一个注解:@ServletComponetScan,指定扫描的包。

2、应用场景

1)过滤敏感词汇(防止sql注入)
2)设置字符编码
3)URL级别的权限访问控制
4)压缩响应信息

2、拦截器

1、实现方式

1.自定义拦截器

@Slf4j
public class AuthInterceptor implements HandlerInterceptor {
    @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        log.info("preHandle");
        String clientIP = ServletUtil.getClientIP(httpServletRequest);
        log.info("访问IP:"+clientIP);
        log.info("请求路径:{}", httpServletRequest.getRequestURI());
        return true;
    }

    @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        log.info("postHandle");

    }

    @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        log.info("afterCompletion");
    }

2.注册拦截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    private final AuthInterceptor authInterceptor;

    public WebMvcConfig(AuthInterceptor authInterceptor) {
        this.authInterceptor = authInterceptor;
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/**");
    }
}

2、应用场景

1.登录验证,判断用户是否登录。
2.权限验证,判断用户是否有权限访问资源,如校验token
3.日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
4.处理cookie、本地化、国际化、主题等。
5.性能监控,监控请求处理时长等。
6.通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)


总结

以上为个人学习过程中对java的一些学习总结,如有错误,欢迎各位批评指导,如有侵权,请联系本人删除,如果觉得有一点帮助麻烦点个赞加收藏!谢谢!

### Java过滤器拦截器区别 #### 出身背景差异 拦截器基于Java的反射机制工作,而过滤器则是基于函数回调来实现其功能[^3]。 #### 实现基础的不同 由于其实现原理上的不同,拦截器并不依赖于Servlet容器即可运行;相比之下,过滤器必须依托于Servlet容器才能正常运作[^2]。 #### 应用范围对比 对于请求类型的覆盖程度而言,拦截器主要适用于Action请求的处理过程之中,而对于其他种类的HTTP请求则未必适用。相反地,过滤器能够应用于几乎所有类型的Web请求路径之上,具有更广泛的适应性。 #### 访问上下文的能力 当涉及到具体的应用环境时,拦截器拥有访问Action上下文中对象的权利,并能操作这些资源。然而,过滤器不具备这样的权限去直接接触或修改此类内部状态数据。 #### 生命周期内的调用次数 在一个完整的应用程序执行周期内,拦截器可以在多个时间点被反复激活并发挥作用,这使得它非常适合用于那些需要频繁介入业务流程的任务当中。但是,过滤器仅能在容器启动初期经历一次性的配置加载阶段之后便不再重复参与后续的操作环节。 #### 集成Spring框架的支持度 值得注意的是,在现代企业级应用开发环境下,特别是采用Spring MVC架构的情况下,拦截器可以从IoC容器中获取各种Bean实例,从而方便地集成复杂的业务逻辑服务组件。这种特性极大地增强了系统的灵活性可维护性。与此同时,传统的过滤器在这方面显得较为局限,无法轻易获得同样的便利条件。 ```java // 这是一个简单的过滤器示例 @WebFilter(filterName = "encodingFilter", urlPatterns = {"/*"}) public class EncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 设置字符集编码 httpResponse.setContentType("text/html;charset=UTF-8"); request.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } @Override public void destroy() {} } ``` ```java // 下面展示了一个基本的拦截器定义方法 @Component public class MyInterceptor extends HandlerInterceptorAdapter { private final Logger logger = LoggerFactory.getLogger(MyInterceptor.class); @Autowired private SomeService someService; // 可以注入服务层的对象 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); logger.info("Before handling the request to URI: {}", uri); // 执行一些前置处理... return true; // 返回true表示继续向下执行处理器链路中的下一个节点 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 处理完成后还可以做一些额外的工作 logger.info("After processing the request."); } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值