網頁

2019/8/24

Spring Boot 設定 Interceptor 攔截器範例

本篇介紹如何在Spring Boot應用程式中設定Inteceptor攔截器,其可攔截傳入Controller的Request及攔截從Controller回傳給Client的Response。




不過Interceptor無法修改response的內容,也就是無法取得及修改response body。若要修改response的內容則使用ResponseBodyAdvice來修改。


範例環境:

  • Windows 64 Bit
  • JDK 1.8.0_171
  • Eclipse 2019-03 (4.11.0)
  • Spring Boot 2.1.6.RELEASE

首先建立一個Spring Boot專案,參考使用Eclipse STS建立Spring Boot應用程式專案

例如Spring Boot現在有一個MessageController如下,其getMessage()用來處理
http://<domain>/<contextPath>/message的請求。
例如在本機為http://localhost:8080/MySpringBoot/message

MessageController

package idv.matt.springboot.controller;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class MessageController {
    
    @GetMapping(value="/message", produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMessage() {
        String message = "お前はもう死んでいる";
        System.out.println("MessageController.getMessage():" + message);
        return message;
    }

}

現在針對這個url請求進行攔截,定義一個攔截器MessageInterceptor類別如下。攔截器類別要實作HandlerInterceptor介面,並記得加上@Component才能被SpringBoot掃描並註冊為Bean。

MessageInterceptor

package idv.matt.springboot.interceptor;

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

import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class MessageInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        
        System.out.println("MessageInterceptor.preHandle():北 斗 殘 悔 拳");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable ModelAndView modelAndView) throws Exception {
        
        System.out.println("MessageInterceptor.postHandle():なに!?");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable Exception ex) throws Exception {
        
        System.out.println("MessageInterceptor.afterCompletion:たわば!!");
    }
}

實作HandlerInterceptor介面可覆寫(override)其三個方法,preHandle()postHandle()afterCompletion()

三個方法的執行時機為:

  1. preHandle():請求送到Controller前執行,回傳一個布林值,如果是true通過攔截器,反之則否。
  2. postHandle():Controller處理完後執行。
  3. afterCompletion():整個請求及回應結束後執行。

然後要將此攔截器註冊到Web MVC的配置,定義一個類別InterceptorWebMvcConfig並實作WebMvcConfigurer介面。

package idv.matt.springboot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import idv.matt.springboot.interceptor.MessageInterceptor;


@Configuration
@EnableWebMvc
public class InterceptorWebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private MessageInterceptor messageInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(messageInterceptor).addPathPatterns("/message/**");
    }
}

此類別名稱前要加上@Configuration@EnableWebMvc annotation表示為Web MVC的配置類別;覆寫addInterceptors(InterceptorRegistry registry)方法, 並調用InterceptorRegistry.addInterceptor()來註冊MessageInterceptor攔截器;最後調用InterceptorRegistration.addPathPatterns()來套用要攔截的url請求路徑。


設定完以上後啟動專案,然後在瀏覽器位址輸入http://localhost:8080/MySpringBoot/message

輸入後在Eclipse的console會印出以下訊息。

MessageInterceptor.preHandle():北 斗 殘 悔 拳
MessageController.getMessage():お前はもう死んでいる
MessageInterceptor.postHandle():なに!?
MessageInterceptor.afterCompletion:たわば!!

以上就是在Spring Boot應用程式加上攔截器的簡單範例。

範例完成後的專案目錄結構如下。




沒有留言:

張貼留言