springboot使用过滤器Filter和拦截器Interceptor

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
    • 过滤器
    • 拦截器
    • 区别
      • 1、实现原理不同
      • 2、使用范围不同
      • 3、触发时机不同
      • 4、拦截的请求范围不同
      • 5、访问范围
      • 6、调用次数
      • 7、操作权限
  • 一、过滤器Filter实现
  • 二、拦截器
  • 实际应用


前言

过滤器

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

拦截器

拦截器(Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置……,在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。

区别

1、实现原理不同

过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。

2、使用范围不同

过滤器实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
而拦截器(Interceptor) 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。

3、触发时机不同

过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

4、拦截的请求范围不同

过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

5、访问范围

filter在servlet前后起作用,拦截器能够深入方法的前后,异常抛出前后。

6、调用次数

在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

7、操作权限

拦截器可以访问action上下文、值、栈里面的对象,而过滤器不可以。拦截器可以获取IOC容器中的各个bean,而过滤器不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

一、过滤器Filter实现

引入相关依赖:

<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

过滤器代码:

package com.example.myblog.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@WebFilter(filterName = "loginFilter", urlPatterns = "/*")
@Order(1)
public class FilterTest implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("初始化 init FilterTest");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String url = ((HttpServletRequest) request).getServletPath();
        System.out.println(url);
        System.out.println(" doFilter FilterTest");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("销毁 destroy loginFilter");
        Filter.super.destroy();
    }
}

测试结果:

springboot使用过滤器Filter和拦截器Interceptor_第1张图片
注意:
@Order(int) 注解,配合 @WebFilter 注解使用,用于多个过滤器时定义执行顺序,值越小越先执行;
filename:过滤器名称;
urlPatterns:过滤器范围;
chain.doFilter(request, response):向下一步执行,如果有其他过滤器,就走其他过滤器,没有就走访问的资源;

二、拦截器

拦截器代码:

package com.example.myblog.Interceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Compent
public class InterceptorTests implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getServletPath();
        System.out.println(url);
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

拦截器配置类代码:

package com.example.myblog.config;

import com.example.myblog.Interceptor.InterceptorTests;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration//定义此类为配置类
public class InterceptorConfig implements WebMvcConfigurer {
	@Autowire
	private InterceptorTests interceptorTests
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addPathPatterns拦截的路径
        String[] addPathPatterns = {
                "/user/**"
        };
        //excludePathPatterns排除的路径
        String[] excludePathPatterns = {
                "/user/login","/user/regist"
        };
        //创建用户拦截器对象并指定其拦截的路径和排除的路径
        registry.addInterceptor(interceptorTests).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
    }
}

测试结果:
在这里插入图片描述

实际应用

拦截器的应用场景:权限控制,日志打印,参数校验。
过滤器的应用场景:跨域问题解决,编码转换。
以上是个人结合网上知识做的总结,如果有错误的地方,还请大家指正。

你可能感兴趣的:(spring,boot,java,spring)