在springboot中配置拦截器、过滤器和监听器

  • 前言
  • 拦截器与过滤器异同
  • 在springboot中配置拦截器
  • 在springboot中配置过滤器的两种方式
  • 监听器
  • 在springboot中配置监听器的两种方式


前言

之前买了两本springboot的书,关于过滤器和监听器的部分基本上是一眼带过的,近日返过去再看发现对于拦截器和过滤器有混淆,打算在这里做个小总结,加深记忆,欢迎交流指正。

拦截器与过滤器异同

拦截器(Intercepter)是spring提供的,既可以用于web程序,也可以用于Application、Swing程序中。在springmvc的DispatchServlet收到请求后,会向HandlerMapper请求查找相应的处理器,HandlerMapper会返回一个执行链,其中可能就包含了一个或多个拦截器。

过滤器(Filter)是Servlet规范中的一个接口,只能用于web应用。它的请求拦截时机在DispatchServlet收到请求之前。

两者都可以做请求合法性的验证、权限检查、通用功能处理等。

关于拦截器和过滤器更加详细的内容可以看一下这位大佬的博客:

在springboot中配置拦截器

在SSM项目中配置拦截器的方法一般是写一个HandlerIntercepter的实现类,重写其中方法,再到springmvc的配置文件中进行注册。springboot支持以纯java的方式进行配置,即可以将一个java类作为配置文件使用。

步骤:
①实现一个拦截器
②在springmvc的配置类中注册

HandlerInterceptor实现类:

public class MyIntercepter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //在处理器处理请求之前执行
        System.out.println("==========执行拦截器!!========");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //在处理器处理请求完成后,返回ModelAndView之前执行。
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //在DispatchServlet完全处理完请求后执行
    }
}

编写拦截器实现类大家应该都不陌生,与传统SSM项目中拦截器无异,区别在于下一步:

@Configuration
public class WebConf implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        registry.addInterceptor(new MyIntercepter())
                //拦截路径
                .addPathPatterns("/user/*")
                //放行路径
                .excludePathPatterns("/user/hello");
    }
}

新建一个类,加上@Configuration注解,该注解表示这是一个配置类交给spring容器处理,并且实现WebMvcConfigurer接口。此时,这个配置类就相当于原本springmvc的配置文件了,你可以在这里注册拦截器、视图解析器、字符集过滤器等。

接下来在类中按下Ctrl+O,找到addInterceptors,重写该方法。将你自己的拦截器注册进去,配置拦截路径、放行路径。addPathPatterns和excludePathPatterns的方法参数都是变长参数(String…patterns),可以将参数用逗号隔开或者直接传一个数组。

在springboot中配置过滤器的两种方式

在springboot中配置过滤器有两种方式,但无论选择哪一种你都得先写一个过滤器,是吧?

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行过滤器!!");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

第一种方式

@Configuration
public class MyWebConf {

    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new MyFilter());
        filter.addUrlPatterns("/*");
        return filter;
    }
}

新建一个配置类,写一个返回值类型为FilterRegistrationBean的方法,在方法上添加@Bean注解,表示将返回值生成一个bean交给spring容器。在方法中新建一个FilterRegistrationBean对象,设置过滤器和拦截路径。

第二种方法
①在你的过滤器类上添加@WebFilter注解,给定拦截路径;如果有多个Filter可以用Order注解指定执行顺序,序号越小,越早被执行。

@Order(1)
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行过滤器!!!");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

②在springboot启动类中注册Filter,只需要添加@ServletComponentScan注解即可

@ServletComponentScan
@SpringBootApplication
public class Demo02Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo02Application.class, args);
    }
}

监听器

监听器是Servlet规范提供的一组接口(一共有8个),用于监听三个作用域对象(请求作用域、会话作用域、全局作用域)的生命周期变化以及作用域中的属性变化,常用于统计在线人数、系统加载时的信息初始化等。

在springboot中配置监听器的两种方式

配置监听器的两种方式与配置过滤器十分相似。
第一种

public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext初始化!!!");
        System.out.println(sce.getServletContext().getServerInfo());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext销毁");
    }
}

@Configuration
public class MyWebConf {
    @Bean
    public ServletListenerRegistrationBean listenerRegistrationBean(){
        ServletListenerRegistrationBean listener = new ServletListenerRegistrationBean();
        listener.setListener(new MyListener());
        return listener;
    }
}

第二种

@WebListener
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext初始化!!!");
        System.out.println(sce.getServletContext().getServerInfo());
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext销毁");
    }
}

@ServletComponentScan
@SpringBootApplication
public class Demo02Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo02Application.class, args);
    }
}