SpringBoot 2.x (7):攔截器


 類似以前SpringMVC的攔截器,但也有一些區別

 

SpringBoot的攔截器有兩種方式:

第一種方式:過時的方式,適用於SpringBoot1.x的方式

package org.dreamtech.springboot.interceptor;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SuppressWarnings("deprecation")
public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/test/*/**");
        super.addInterceptors(registry);
    }
}

 

第二種方式:基於Java8與Spring5的方式

原理:在WebMvcConfigurer接口中定義了默認方法,利用Java8新特性:接口中可以寫方法

package org.dreamtech.springboot.interceptor;

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 CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

 

LoginInterceptor:只是實現了三個基本方法,分別打印一句話,了解執行順序:

package org.dreamtech.springboot.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 攔截之前調用(進入Controller之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("[ preHandle LoginInterceptor ]");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    /**
     * 調用方法之后,視圖渲染之前
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("[ postHandle LoginInterceptor ]");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 完成攔截之后,用於清理資源
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("[ afterCompletion LoginInterceptor ]");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

 

Controller:

package org.dreamtech.springboot.controller;

import java.util.HashMap;
import java.util.Map;

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

@RestController
public class DemoController {

    @RequestMapping("/login/account")
    private Object account() {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        modelMap.put("money", 1000);
        System.out.println("[ account DemoController ]");
        return modelMap;
    }
}

 

訪問localhost:8080/login/account打印情況如下:

[ preHandle LoginInterceptor ]
[ account DemoController ]
[ postHandle LoginInterceptor ]
[ afterCompletion LoginInterceptor ]

 

如果沒有以上打印,要注意這幾點:

1.是否有@Configuration注解

2.是否將攔截路徑寫成/xxx/*/**,如果是/xxx/*/*就會攔截失敗

 

同樣地,我們可以添加多個攔截器

        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/test/*/**");
        registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/demo/*/**");

 

或者鏈式調用:攔截所有路徑,但不包括/login

registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");

 

多個攔截器的調用順序:可以理解為包裹的方式

package org.dreamtech.springboot.interceptor;

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 CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
        registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/login/*/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

DemoInterceptor和LoginInterceptor內容基本一致

最終的打印:

[ preHandle LoginInterceptor ]
[ preHandle DemoInterceptor ]
[ account DemoController ]
[ postHandle DemoInterceptor ]
[ postHandle LoginInterceptor ]
[ afterCompletion DemoInterceptor ]
[ afterCompletion LoginInterceptor ]

 

最后:

Filter和Interceptor的區別:

1.Filter基於Servlet,而Interceptor不依賴於Servlet容器

2.Filter只在容器被初始化的時候被調用一次,Interceptor次數沒有限制

3.Interceptor基於AOP思想,Filter基於doFilter方法

 

兩者的執行順序:

過濾前->攔截前->Controller->攔截后->過濾后


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM