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抽象類重寫裏面的方法,然後在攔截器配置類裏面配置即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章