以前在【快學springboot】6.WebMvcConfigurer配置靜態資源和解決跨域裏有用到WebMvcConfigurer接口來實現靜態資源的映射和解決跨域請求,而且在文末還說了WebMvcConfigurer(springboot2.x以後使用該接口,springboot1.x使用WebMvcConfigurerAdapter類,不過該類已經被標識過時了)能夠配置不少東西,以下:java
下面,咱們就經過代碼,使用WebMvcConfigurer接口來實現一個springboot的攔截器。spring
這裏都是基於以前的項目開發的,以前的WebConfig.java以下:跨域
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**")
.addResourceLocations("file:D:\"); } /** * 跨域支持 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH") .maxAge(3600 * 24); } } 複製代碼
以前已經實現了靜態資源和解決跨域問題的配置。咱們能夠重寫WebMvcConfigurer的addInterceptors方法來實現攔截器:springboot
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
複製代碼
咱們只須要經過registry.addInterceptor( )添加一個攔截器便可bash
新建一個RequestInterceptor.java,實現HandlerInterceptor接口,以下:app
@Component
public class RequestInterceptor implements HandlerInterceptor {
}
複製代碼
這裏別忘了加上Component註解。ide
咱們能夠經過接口的方法列表查看下,咱們能夠實現那些功能:post
能夠看到,咱們能夠實現preHandle、postHandle和afterCompletion這三個方法。ui
preHandlespa
preHandle 方法,經過字面意思不難理解,此方法會在處理每一個請求以前先執行。此方法的返回一個布爾值,若是返回爲false ,表示請求結束。咱們重寫該方法,直接返回一個false:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("請求進來了");
return false;
}
複製代碼
而且把該攔截器在WebConfig中進行註冊:
這時候啓動項目,攔截器已經能夠起做用了,不過這時候訪問會沒有返回,咱們能夠經過response來返回一些信息,以下:
這時候,直接訪問項目根路徑:
查看控制檯
若是有全局異常捕獲的話,咱們還能夠經過拋出異常的形式來返回值。
postHandle
這個方法是處理請求以後,可是在返回數據以前執行的。咱們能夠經過這樣一個方法(這個方法是以前文章裏有的啦)來驗證,在return處打一個端點:
@PostMapping
public Object addUser() {
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
return "OK";
}
複製代碼
實現postHandle方法,以下:
運行程序,請求接口:
在斷點處停了下來,可是並無看到控制檯輸出了「執行了postHandle」。
afterCompletion
顧名思義,這個方法實在處理完成而且返回結果以後執行的。這個方法更可能是用來關閉一些資源的吧,好比ThreadLocal,日誌MDC之類的。實現afterCompletion方法以下:
咱們在sout出打一個斷點,而後發起接口請求。效果以下:
線程在斷點處中止了,可是請求已經拿到了數據。不過須要注意的是,若是在處理請求出現異常的時候,該方法仍是會在返回數據以前執行的(Exception參數就是給咱們處理異經常使用的),而且你能夠拿到執行時所拋出的異常信息(沒有配置異常攔截器的話,若是配置餓了異常攔截器,ex會爲null,因此咱們須要先把全局異常攔截器去掉)。修改controller方法以下:
@PostMapping
public Object addUser() {
// 新增一個用戶
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
throw new RuntimeException();
// return "OK";
}
複製代碼
使他拋出一個異常。而後執行請求:
只是後,postman還在等待數據,而且程序執行到了斷點處。而且能夠看到,ex就是咱們手動拋出的異常。
把斷點放掉,postman成功拿到了數據。其實咱們也能夠經過這個來作一個全局異常處理器,不過徹底沒有這個必要性。