Springboot——インターセプター

### 1.インターセプターの用途
（1）未ログインのユーザーが特定のリンクに直接アクセスするのを防ぐ
（2）ログ情報をキャプチャする
（3）SQLインジェクションなどの不正攻撃を防ぐ

### 2.係わるjar、クラス
（1）spring-webmvc.jar
（2）**HandlerInterceptor**(org.springframework.web.servlet：インターフェース)、
**AsyncHandlerInterceptor**(org.springframework.web.servlet：インターフェース)、
**HandlerInterceptorAdapter**(org.springframework.web.servlet.handler.HandlerInterceptorAdapter：抽象クラス)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809422/6c777d44-c1cc-b21c-8e8c-44ccb448ef20.png)

### 3.インターセプターの実行順序
実行順序：preHandle -> controller -> postHandle -> afterCompletion
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809422/86cd003d-4b2b-f51e-dd6b-4c3a10002aa7.png)

### 4. インターセプターの具体的な使用例（コード実装）
(1) インターセプターの作成（preHandleが最も実用的）
```
/**
 * ログインチェック
 * 1. インターセプターでどのリクエストをインターセプトするかを設定
 * 2. これらの設定をコンテナに登録
 *
 * HandlerInterceptorインターフェースの実装
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目標メソッドの実行前
     * ログインチェックはここに記述し、ログインしていない場合、目標メソッドは実行しない
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//      インターセプターを通過するパスを取得
        String requestURI = request.getRequestURI();

        //      ログインチェックロジック
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser !=null){
//          許可
            return true;
        }
//      インターセプト つまり、未ログインの場合、自動的にログインページにリダイレクトし、インターセプトロジックを記述
        return false;
    }

    /**
     * 目標メソッドの実行後
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * ページレンダリング後
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
```
(2) インターセプターをコンテナに追加する
```
@Configuration
// Spring MVCの機能をカスタマイズするためにWebMvcConfigurerを使用
public class AdminWebConfig implements WebMvcConfigurer {

    /**
     * インターセプターの設定
     * @param registry インターセプターの登録センターに相当
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//       以下のコードはインターセプターを追加することに相当します。追加するインターセプターは先ほど作成したものです。
        registry.addInterceptor(new LoginInterceptor())
//       addPathPatterns()は、どのパスをインターセプトするかを設定します。addPathPatterns("/**")はすべてのリクエストをインターセプトします（静的リソースも含む）。
//       addPathPatternsを明示的に指定しない場合、インターセプターはデフォルトですべてのパスをインターセプトします。
                .addPathPatterns()
//       excludePathPatterns()は、インターセプターを通過させるパスを設定します。
//       excludePathPatterns("/","/login")は「/」および「/login」リクエストを通過させます。
//       静的リソースがある場合、ここで通過させることができます。
                .excludePathPatterns("/","/login");
    }
}

```

### 5. request.getHeader の基本的な使用方法

request.getHeader メソッドは、**HTTPリクエストのヘッダー**から特定の情報を取得するために使用されます。
```
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // リクエストヘッダーから "Content-Type" を取得
    String contentType = request.getHeader("Content-Type");
    // コンソールに "Content-Type" ヘッダーの値を出力
    System.out.println("preHandle... Content-Type: " + contentType);

    // 処理を続けるために true を返す
    return true;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809422/c12f50ac-1632-4673-4a57-283af1f47e75.png)
```
//コンソールに出力される例:
preHandle... Content-Type: application/json
```