SpringBoot配置Filter和Interceptor【附带源码】

博客优先发表在个人博客,后续更新可能忘记同步到CSDN,望理解。
个人博客本篇文章地址:https://www.xdx97.com/article/698261857995063296


一、先看一下目录结构

在这里插入图片描述

二、我们先配置启动类和配置文件

这里面其实没有什么东西,但是为了完整性还是都写出来,防止有的朋友弄错。

app

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {"www.xdx97"})
public class app {

    public static void main(String[] args) {
        SpringApplication.run(app.class,args);
    }
}

application.yml

server:
  port: 9000

Controller

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

    @GetMapping("/xdx/test")
    public String test(){
        System.out.println("哈哈");
        return "haha";
    }
}

三、配置拦截器

InterceptorOne

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class InterceptorOne extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("拦截器One  -  过");
        return true;
    }
}

InterceptorTwo

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class InterceptorTwo implements HandlerInterceptor {


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        System.out.println("拦截器Two  -  过");
        return true;
    }
}

WebAppConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import www.xdx97.interceptor.InterceptorOne;
import www.xdx97.interceptor.InterceptorTwo;

/*
拦截器配置类
 */
@Configuration
public class WebAppConfig implements WebMvcConfigurer {

    // 多个拦截器组成一个拦截器链
    // addPathPatterns 用于添加拦截规则
    // excludePathPatterns 用户排除拦截

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new InterceptorOne())//添加拦截器
                .addPathPatterns("/**") //拦截所有请求
                .excludePathPatterns("/UserCon/**", "/Doctor/**", "/SMS/**");//对应的不拦截的请求

        registry.addInterceptor(new InterceptorTwo())
                .addPathPatterns("/**")
                .excludePathPatterns("/UserCon/**", "/Doctor/**", "/SMS/**");
    }
}

到这里我们可以启动我们的项目然后去访问 http://localhost:9000/xdx/test 可以看到,两个拦截器依次进入了。

在拦截器里面我们可以做具体的业务,返回 true 是放行,false 就是不放行。

拦截器的顺序就是在 addInterceptors 方法里面加入的顺序。

我们也可以看到要实现拦截器,我们有两种方式,它们都是一样的去重写父类里面的方法。

  • implements HandlerInterceptor
  • extends HandlerInterceptorAdapter

拦截器里面的方法作用

  • preHandle                  开始进入地址拦截器
  • postHandle                处理请求完成后视图渲染之前的处理操作
  • afterCompletion         视图渲染之后的操作

四、配置过滤器

4-1、使用 @WebFilter 注解

FilterOne

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Component
@WebFilter(filterName = "FilterOne", urlPatterns = "/*")
@Order(3)
public class FilterOne implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("FilterOne");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

FilterTwo

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Component
@WebFilter(filterName = "FilterTwo", urlPatterns = "/*")
@Order(2)
public class FilterTwo implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("FilterTwo");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

这样你再次启动访问就可以看到请求会先进入过滤器、再进入拦截器的


4-2、使用 @Bean 注解

FilterThree

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import java.io.IOException;

@Component
@Order(1)
public class FilterThree implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("FilterThree");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

在WebAppConfig里面加入下面的方法,也可以在启动类里面加入

    @Bean
    public FilterRegistrationBean testFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean(new FilterThree());
        registration.addUrlPatterns("/**");
        registration.setName("FilterThree");
        return registration;
    }

这时候你再启动去访问,就会看到请求也会进入 FilterThree

这个 @Order(1) 是表示优先度,数字越小优先度越高。

我看有很多人说这个注解无效,我以前写了一篇文章也用到了这个注解,然后也有人评论说无效,但是我今天反复测试这个注解是有效的


五、其它

使用这个拦截器来做登录拦截的时候有一个很好的思路:我们写一个注解 @Login 当方法有这个注解的时候我们才做登录拦截,没有就放行。

如果你的拦截器或者过滤器无效,看看他们是否在Spring扫描的范围内。

关注公众号回复关键字获取源码噢: Filter&InterceptorDemo

在这里插入图片描述

参考:
https://blog.csdn.net/xiaodanjava/article/details/32125687


六、面试

如果是以前,这篇文章到五也就结束了,但是现在我觉得我得时刻为面试做准备。怕了怕了!!!

你用过拦截器和过滤器吧?你简单得说说它们

    Filter: 它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理。

    Interceptor: 拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作。


Filter和Interceptor的区别

  • Filter是基于函数回调的,而Interceptor则是基于Java反射的。
  • Filter依赖于Servlet容器,而Interceptor不依赖于Servlet容器。
  • Filter对几乎所有的请求起作用,而Interceptor只能对action请求起作用。
  • Interceptor可以访问Action的上下文,值栈里的对象,而Filter不能。
  • 在action的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。

Filter和Interceptor的执行顺序

    过滤前-拦截前-action执行-拦截后-过滤后


怎么去实现一个Filter和Interceptor呢

    Filter:首先去实现Filter接口,重写里面的doFilter方法,然后可以使用 @WebFilter@Bean来实现

    Interceptor:可以通过实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter抽象类重写里面的方法,然后在拦截器配置类里面配置即可

猜你喜欢

转载自blog.csdn.net/Tomwildboar/article/details/105442514