spring boot整合web開發(fā)-4-注冊(cè)、配置攔截器

攔截器原理:

攔截器的原理很簡單,是 AOP 的一種實(shí)現(xiàn),專門攔截對(duì)動(dòng)態(tài)資源的后臺(tái)請(qǐng)求,即攔截對(duì)控制層的請(qǐng)求。使用場(chǎng)景比較多的是判斷用戶是否有權(quán)限請(qǐng)求后臺(tái),更拔高一層的使用場(chǎng)景也有,比如攔截器可以結(jié)合 websocket 一起使用,用來攔截 websocket 請(qǐng)求,然后做相應(yīng)的處理等等。

注冊(cè)攔截器

步驟01 創(chuàng)建一個(gè)spring boot項(xiàng)目,添加spring-boot-starter-web依賴
步驟02 創(chuàng)建攔截器實(shí)現(xiàn)HandlerInterceptor接口

package xintianweng;
import org.apache.catalina.filters.ExpiresFilter;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;

/**
 * 創(chuàng)建一個(gè)攔截器
 * @author 信天翁
 * 2021/3/29 10:00 下午
 **/
public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
        System.out.println("MyInterceptor>>>preHandle");
        return true;
    }
    public void postHandle(HttpServletRequest request, ExpiresFilter.XHttpServletResponse response, Object handler, ModelAndView modelAndView){
        System.out.println("MyInterceptor>>>postHandle");
    }
    public void afterCompletion(HttpServletRequest request, ExpiresFilter.XHttpServletResponse response, Object handler,Exception ex){
        System.out.println("MyInterceptor>>>afterCompletion");
    }
}

攔截器中的方法將按preHandle??Controller??postHandle??afterCompletion的順序執(zhí)行。
注意,只有當(dāng)preHandle方法返回true時(shí)后面的方法才會(huì)執(zhí)行。
當(dāng)攔截器鏈內(nèi)存在多個(gè)攔截器時(shí),postHandler在攔截器鏈內(nèi)的所有攔截器返回成功時(shí)才會(huì)調(diào)用,而afterCompletion只有preHandle返回true才調(diào)用,但若攔截器鏈內(nèi)的第一個(gè)攔截器的preHandle方法返回false,則后面的方法都不會(huì)執(zhí)行。

步驟03 配置攔截器。定義配置類進(jìn)行攔截器的配置

package xintianweng;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置攔截器
 * @author 信天翁
 * 2021/3/29 10:00 下午
 **/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/hello");
    }
}

preHandle(……) 方法:該方法的執(zhí)行時(shí)機(jī)是,當(dāng)某個(gè) url 已經(jīng)匹配到對(duì)應(yīng)的 Controller 中的某個(gè)方法,且在這個(gè)方法執(zhí)行之前。所以 preHandle(……) 方法可以決定是否將請(qǐng)求放行,這是通過返回值來決定的,返回 true 則放行,返回 false 則不會(huì)向后執(zhí)行。

postHandle(……) 方法:該方法的執(zhí)行時(shí)機(jī)是,當(dāng)某個(gè) url 已經(jīng)匹配到對(duì)應(yīng)的 Controller 中的某個(gè)方法,且在執(zhí)行完了該方法,但是在 DispatcherServlet 視圖渲染之前。所以在這個(gè)方法中有個(gè) ModelAndView 參數(shù),可以在此做一些修改動(dòng)作。

afterCompletion(……) 方法:顧名思義,該方法是在整個(gè)請(qǐng)求處理完成后(包括視圖渲染)執(zhí)行,這時(shí)做一些資源的清理工作,這個(gè)方法只有在 preHandle(……) 被成功執(zhí)行后并且返回 true 才會(huì)被執(zhí)行。

自定義類實(shí)現(xiàn)WebMvcConfigurer接口,實(shí)現(xiàn)接口中的addInterceptors方法。其中,
addPathPatterns是用來表示攔截路徑。
excludePathPatterns是用來表示排除的路徑。

templates下創(chuàng)建hello.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    spring boot !
</body>
</html>

執(zhí)行springboot啟動(dòng)類,控制臺(tái)輸出如下:

MyInterceptor>>>>preHandle
HELLO SPRING BOOT!
MyInterceptor>>>>postHandle
MyInterceptor>>>>afterCompletion

總結(jié):
①:首先會(huì)在攔截到Controller中的“/hello”時(shí)先執(zhí)行preHandle里的邏輯。輸出“MyInterceptor>>>>preHandle”
②:然后執(zhí)行“/hello”對(duì)應(yīng)映射的方法邏輯,輸出“HELLO SPRING BOOT!”
③:成功執(zhí)行“/hello”對(duì)應(yīng)映射的方法邏輯,然后在 DispatcherServlet 視圖渲染之前執(zhí)行postHandle方法里的邏輯。
④:整個(gè)請(qǐng)求結(jié)束后,然后在這里執(zhí)行一些其他輔助邏輯,包括資源清理等。

攔截器處理靜態(tài)資源被攔截的問題

spring boot 2.0以后廢棄了WebMvcConfigurerAdapter,但是WebMvcConfigurationSupport 又會(huì)導(dǎo)致默認(rèn)的靜態(tài)資源被攔截

手動(dòng)放開靜態(tài)資源攔截:(和上面的手動(dòng)配置攔截器一樣,在原來的>addInterceptors方法外,還需要重寫addResourceHandlers,將資源放開)

    protected void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容