Web APIを実装する(3)
Spring MVCの動作を変更するコンフィギュレーションクラス
Spring MVCで共通のアクセスコントロールや、共通のリクエストに対する処理、静的ファイルの指定などを行う場合には、WebMvcConfigurerインターフェースを実装したクラスをBean定義しておくと自動的にその設定が有効になります。
WebMvcConfigureで設定できる項目は、JavaDocに詳細がありますが、よく利用する設定として表4があります。
設定時に利用するメソッド | 概要 |
---|---|
addCorsMappings | Cors(Cros:Cross-origin resource sharing)でのリクエストに対応するための設定 |
addFormatters | リクエストデータのフォーマット変換処理の登録。例えば、文字列から日付形式など |
addInterceptors | リクエストに対する処理の前後に追加で行う処理を登録。例えば、リクエストに対するアクセス制限やヘッダ操作等など |
addResourceHandlers | 静的リソース(HTMLやJavaScript、画像、CSS等)の登録 |
configureMessageConverters | クエスト・レスポンスデータ形式変換処理の登録。例えば、文字列からバイト形式など |
リスト6は、Web APIにおけるCorsリクエストに対応する場合のサンプルコードです。
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; // (省略) @Configuration // (1) WebMvcConfigurerインターフェースを実装したクラスを作成 public class WebConfiguration implements WebMvcConfigurer { @Override // (2) addCorsMappingsの指定例 public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/contact/**") .allowedOrigins("*") .allowedMethods("GET","POST","DELETE") .allowedHeaders("Content-Type","accept","Origin") .allowCredentials(false).maxAge(3600); } // (省略) }
(1)のようにWebMvcConfigurerインターフェースを実装したクラスを作成し、@Configurationを使ってBean登録します。
(2)でaddCorsMappingsメソッドを使ってCORSリクエストを/contact以下のすべてのアクセスに受け入れるように指定します。
こういった流れで、Spring MVCで設定を変更していきます。その他の設定方法についてはSpring MVCのドキュメントに記されているので参考にしてください。
サーブレットフィルタを使う
サーブレットフィルタでも同様の実装が可能な場合があります。WebMvcConfigureよりもサーブレットAPI側で処理を行った方がわかりやすい方もいると思います。
Spring Bootでフィルタを実装する場合には、org.springframework.web.filter.GenericFilterBeanクラスを継承したクラスを作成し、そのオブジェクトをBean登録すると自動的にフィルタが有効になります。
リスト7は、サーブレットAPIのフィルタ機能を使って、Corsでのリクエストを許可する場合のサンプルコードです。
: (省略) import org.springframework.web.filter.OncePerRequestFilter; @Component public class CorsFilter extends OncePerRequestFilter { // (1) 利用するフィルタクラス // (2) フィルタの実装 @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", "*"); if ("OPTIONS".equals(request.getMethod())) { response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Content-Type"); response.setStatus(HttpServletResponse.SC_OK); } else { filterChain.doFilter(request, response); } } }
(1)では、GenericFilterBeanを継承したOncePerRequestFilterクラスを使っています。このクラスは1つのリクエスト内で必ず1回しか実行されないフィルタクラスです。
フィルタは同一リクエストであっても場合によっては複数回実行されますが、アクセス制御など、1回しか動かない方が都合が良い場合があります。そのようなケースのために、SpringではOncePerRequestFilterクラスが用意されています。
また、GenericFilterBeanクラスを利用した場合には、doFilterメソッドを使って処理を実装しますが、OncePerRequestFilterクラスを使った場合には、(2)のようにdoFilterInternalを利用します。
ただし、このフィルタを有効にすると先ほど紹介したWebMvcConfigurerでのCorsの動作を無効にしてしまうので、通常はWebMvcConfigurerを利用することをおすすめしますが、Spring MVCでもサーブレットレベルでの設定が可能です。
最後に
Spring MVCについて今回紹介した内容だけでは紹介しきれない内容がまだまだたくさんあり、Spring MVCの全体について本記事だけで詳細を紹介することは難しいです。
しかし、全体の流れについてを把握した上でSpring MVCのドキュメントと実際のサンプルコードなどを参照すると理解がより深まります。
次回はデータベース関連のアノテーションなど機能部分について紹介します。
参考資料
本連載の書籍が発売されました!
Javaによる高速Webアプリケーション開発のためのSpring Boot入門
著者:WINGSプロジェクト 小林昌弘
発売日:2020年5月31日(水)
価格(POD):2,200円(税込)
価格(電書):1,760円(税込)