SpringMVC－Interceptor機能

# Interceptorとは

SpringFrameworkでは\@Controllerアノテーションを付けたControllerクラスがリクエストを受けてレスポンスを返す処理を行う。
ControllerクラスはDispatcherServletがリクエストURLからControllerクラスを抽出して実行する。
Inerceptorは、画面処理の前後とリクエストの一番最後に呼び出される割り込み処理で、Inerceptorを使うとControllerの実行前後に処理を追加することができる。
例えば、アクセス元のIPアドレスをログに出力する場合はInterceptorを使う。

*Spring MVC の処理フロー*
![Spring MVC の処理フロー](https://584bde64-a-62cb3a1a-s-sites.googlegroups.com/site/soracane/home/springnitsuite/spring-mvc/1-ji-ben-gai-nian-quan-ti-dena-chu-lifuro/mvc_dispatch_overall3.JPG?attachauth=ANoY7crsIwphwDmGm8FjFACS3pMIzjixrCCXecsIIkE7vmT1v68wfB6-ynklNVnr42mVdQMoPZzTJXIH9lHW_Yb6CJMTm10vSOUT5jpmLpBvOXCtL-c3mHRkp1kTLrroI0theDZM4rrL-Jo5dlfamE2p2N28_02FL5ZxRZGVLTAq8JhppxhwT3e0X2g2gV8mrxTcoRyTLYOcHGXhqmQck9C70pGyuJ4VeRA9V9P-1waheYDWCGVihIZqB3R3K9qqRLSzYAI2-KfUUMEnBRfqgVxbA-Lz8w5QjxrZb9q-jhDu2g7nte0sXAggPpob8AWDBx20IBkX4xzB0hFhV7rfccjp7XEvwo9Ldg%3D%3D&attredirects=0)

引用
[soracane 01．基本概念：全体的な処理フロー](https://sites.google.com/site/soracane/home/springnitsuite/spring-mvc/1-ji-ben-gai-nian-quan-ti-dena-chu-lifuro)

## Interceptorの仕組み

実態：org.springframework.web.servlet.HandlerInterceptorインターフェース
HandlerInterceptorインターフェースをDispatcherServletが実行している。

| メソッド | 戻り値 | 実行タイミング |
|:--|:--:|:--|
| preHandle | booean | Controller実行前 |
| postHandle | void | Controller実行後～viewレンタリング前 |
| afterCompletion | void | viewレンタリング後 |

[HandlerInterceptorのAPIReference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/HandlerInterceptor.html)

## Interceptorの作成方法

Interceptorを使ってアクセスしてきたIPアドレスをログファイルに出力してみる。

<手順>
1. org.springframework.web.servlet.HandlerInterceptorの実装クラスを作成する
1. applicationContext.xmlにインタセプターを定義する

なお、SpringMVCプロジェクトは下記の手順で作成したものを使用する
[SpringMVCプロジェクト](http://www.tekboy.net/archives/544)

＜今回検証した各モジュールのバージョン情報＞

| モジュール | version |
|:--------------------|:--:|
| STS | 3.9.9 |
| JDK | 1.8.0_221 |
| Tomcat | 8.5 |
| SpringFramework | 3.1.1 |
| Thymeleaf | 2.1.6 |

### Interceptorの作成方法①

org.springframework.web.servlet.HandlerInterceptorの実装クラスを作成し、
preHandleメソッド内でIPアドレスを出力する。

```HogeIntercepter.java
package hogehoge;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class HogeIntercepter implements HandlerInterceptor {

	private static final Logger logger = LoggerFactory.getLogger(HogeIntercepter.class);
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO 自動生成されたメソッド・スタブ
		logger.info("URI：" + request.getRequestURI()); 
		logger.info("IPアドレス：" + request.getRemoteAddr()); 
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO 自動生成されたメソッド・スタブ

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO 自動生成されたメソッド・スタブ

	}
}

```

### Interceptorの作成方法②

applicationContext.xmlにインタセプターを定義する。

```applicationContext.xml
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

・
・
・

	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<beans:bean class="hogehoge.HogeIntercepter" />
		</mvc:interceptor>
	</mvc:interceptors>

</beans:beans>
```
### 実行結果

<details>
<summary>ログ出力内容</summary>
INFO : hogehoge.HogeIntercepter - URI：/hogehoge/
INFO : hogehoge.HogeIntercepter - IPアドレス：0:0:0:0:0:0:0:1
</details>

## 参考サイト

[soracane Spring-MVC](https://sites.google.com/site/soracane/home/springnitsuite/spring-mvc)
[トッカンソフトウェア　Spring MVC インターセプター](https://tokkan.net/spring/interceptor.html)