Spring Bootでフィルタ(Filter)する方法

Spring BootでFilterを実装する方法です。

Spring BootでFilterする方法

Spring Boot では web.xml がありません。では、どうやったら Filter を実装できるのか・・・その方法を紹介します。複数 Filter する方法も掲載しておきます。

これから Spring BootでWebアプリを開発しようという方 のお役に立てればうれしいです。


環境

Spring BootでFilterを実装する

Filter インターフェースの実装クラスを作ってコンテナ登録します。

package springbootapp;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

@Component
public class LoggingFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("[Spring BootでFilterを実装] : init");
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
    System.out.println("[Spring BootでFilterを実装] : doFilter");
    chain.doFilter(request, response);
  }
  @Override
  public void destroy() {
    System.out.println("[Spring BootでFilterを実装] : destroy");
  }
}

構成はこんな感じです。

Spring BootでFilter実装

実行してログをみてみると・・・

2016-11-17 13:03:32.012  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-11-17 13:03:32.016  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-11-17 13:03:32.017  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-11-17 13:03:32.017  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-11-17 13:03:32.017  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-11-17 13:03:32.017  INFO 8592 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'loggingFilter' to: [/*]
[Spring BootでFilterを実装] : init
・・・省略・・・
[Spring BootでFilterを実装] : doFilter

おおお、フィルターされましたねー^^

上記のログから、お馴染みの CharacterEncodingFilter が設定しなくても動いているがわかります。これは HttpEncodingAutoConfiguration によって自動登録されるため、デフォルトエンコーディングとして設定されている「UTF-8」を使う場合は設定する必要がありません。簡単だなー^^

Spring BootでFilterを複数実装する

上で作った LoggingFilter を LoggingFilter1 に名前を変え、LoggingFilter2 としてコピーします。実行順わかりやすいように sysout に「その1」とか「その2」とか付けておきます。

@Component アノテーションは削除しておきます。

package springbootapp;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LoggingFilter1 implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("[Spring BootでFilterを実装 その1] : init");
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
    System.out.println("[Spring BootでFilterを実装 その1] : doFilter");
    chain.doFilter(request, response);
  }
  @Override
  public void destroy() {
    System.out.println("[Spring BootでFilterを実装 その1] : destroy");
  }
}

package springbootapp;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LoggingFilter2 implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("[Spring BootでFilterを実装 その2] : init");
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
    System.out.println("[Spring BootでFilterを実装 その2] : doFilter");
    chain.doFilter(request, response);
  }
  @Override
  public void destroy() {
    System.out.println("[Spring BootでFilterを実装 その2] : destroy");
  }
}

WebConfig クラスを作って、WebMvcConfigurerAdapter を extened します。メソッドに @Bean アノテーションを書くことによって、複数のフィルタを追加できます。

package springbootapp;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  @Bean
  public FilterRegistrationBean filter1() {
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setFilter(new LoggingFilter1());
    bean.setOrder(2);
    return bean;
  }
  @Bean
  public FilterRegistrationBean filter2() {
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setFilter(new LoggingFilter2());
    bean.setOrder(1);
    return bean;
  }
}

構成はこんな感じです。

Spring Bootで複数Filter実装

実行してログをみてみると・・・

2016-11-17 13:27:03.388  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-11-17 13:27:03.388  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-11-17 13:27:03.389  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-11-17 13:27:03.389  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-11-17 13:27:03.389  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'loggingFilter2' to: [/*]
2016-11-17 13:27:03.389  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'loggingFilter1' to: [/*]
2016-11-17 13:27:03.389  INFO 6716 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
[Spring BootでFilterを実装 その2] : init
[Spring BootでFilterを実装 その1] : init
・・・省略・・・
[Spring BootでFilterを実装 その2] : doFilter
[Spring BootでFilterを実装 その1] : doFilter

おおお、フィルターされましたねー^^

setOrder プロパティでフィルターの登録順を設定できます。多分、メソッドを書いた順番で動くと思うんですけど、明示的にしておけば安心ですので。

まとめ

Spring BootでFilterを実装する方法を紹介しました。

これで web.xml なしでフィルター実装できることがわかりましたね。

Servlet は 3.0 になってからアノテーションを利用することで Servlet の設定が単純になりました。一度はプログラミングの外に設定を追い出したはずなのに、アノテーションを利用することでまたプログラミングの中に記述するスタイルに戻った・・・ということですかね。さて、どっちがメリット高いのか・・。設定は外出ししておいた方がメンテナンス性は向上しそうだけど、生産性はどうなんだって・・・。永遠のテーマなんでしょうかねー^^;

次は開発と本番で設定ファイルを切り替えるあたりを検証しましょうかね。

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。