SpringでInterceptorを利用する(SpringBoot)

Interceptorとは?

Interceptorは、画面処理の前後とリクエストの一番最後に呼び出される割り込み処理のこと。
Interceptorを使うとControllerの実行前後に処理を追加することができる。

実装する場合には、org.springframework.web.servlet.HandlerInterceptorインターフェースを実装する。

public class SampleInterceptor implements HandlerInterceptor {
  //...
}

HandlerInterceptorには以下の3つのメソッドが定義されている。

preHandle

コントローラーの実行前の処理を定義する。
戻り値の型はboolean型でtrueであればコントローラーの処理を実行し、falseであればコントローラーの処理を実行せずに200のレスポンスを返却する。
引数のhandlerから実行されるコントローラーを取得する事ができる。

@Override
public boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, Object handler) throws Exception {
  //...
  return true;
}

postHandle

コントローラーの実行後の処理を定義する。
MVCの場合はテンプレートエンジンによるレンダリングの前に実行される処理で、REST API の場合はレスポンス送信前の処理に実行される。
コントローラーの処理中に例外が発生した場合、このメソッドは実行されない。

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
    Object handler, @Nullable ModelAndView modelAndView) throws Exception {
  //...
}

afterCompletion

クライアントへレスポンスを送信した後の処理を定義する。
MVC の場合は、テンプレートエンジンによるレンダリングが完了してレスポンスを送信後に実行される。
exにはレンダリングで発生した例外が設定され、コントローラーでスローされた例外が設定されるわけではない。
コントローラーで例外がスローされても実行される。

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
    Object handler, @Nullable Exception ex) throws Exception {
  //...
}

Interceptorの定義方法

作成したインターセプターはDIコンテナへの登録と、SpringにInterceptorを追加したことを教えてあげる必要がある。

■ DIコンテナへの登録

@Configuration
public class BeanConfiguration {

    @Bean
    public SampleInterceptor sampleInterceptor() throws Exception{
        return new SampleInterceptor();
    }

}

■ インターセプターの追加

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    HandlerInterceptor sampleInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(displayIdInterceptor())
            // インターセプターの実行対象外とするURLを設定する
            // 設定していない場合は全てのURLが実行対象となる
            .excludePathPatterns("/images/**")
            // インターセプターの実行対象とするURLを設定する
            .addPathPatterns("/sample")
            // インターセプターの適用順序を設定(デフォルト:0)
            // 特に設定していない場合追加した順に実行される
            .order(1);
    }
}