Spring MVC は Spring Framework の Servlet ベース Web フレームワークです。フロント
コントローラーである DispatcherServlet は、リクエストマッピング、引数解決、
コントローラー呼び出し、戻り値処理、例外変換を調整します。Spring WebFlux は異なる
リアクティブランタイムとスレッドモデルを使用するため、両フレームワークを交換可能
なものとして扱ってはなりません。
ブートストラップとディスパッチ #
Boot ではない Servlet アプリケーションは、WebApplicationInitializer を通じて Web
アプリケーションコンテキストとディスパッチャーを登録できます。
public final class WebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
var context = new AnnotationConfigWebApplicationContext();
context.register(WebConfiguration.class);
var servlet = servletContext.addServlet(
"mvc", new DispatcherServlet(context));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}Spring Boot は MVC アプリケーションに対して同等の登録を行います。ディスパッチャーを
/ にマッピングすると、Servlet コンテナーは静的リソースと JSP の特別な処理を維持
できます。/* ではそれらのディスパッチも捕捉します。
各リクエストで、ディスパッチャーは次を行います。
- 順序付けられた
HandlerMapping実装にハンドラーとインターセプターを要求する。 - そのハンドラーを呼び出せる
HandlerAdapterを選択する。 - pre-handle インターセプターとハンドラーを呼び出す。
- 戻り値をレスポンスボディ、ビュー、非同期結果、その他の対応形式として処理する。
- 例外リゾルバーと完了インターセプターを実行する。
MVC の戦略オブジェクトはディスパッチャーコンテキストの Bean です。
@EnableWebMvc は通常の Spring アプリケーション向け標準設定をインポートします。
Spring Boot では、自動設定を完全に引き取る @EnableWebMvc を追加する代わりに、
WebMvcConfigurer を実装して Boot の設定を拡張します。
リクエストマッピング、バインディング、検証 #
アノテーション付きコントローラーは、パス、HTTP メソッド、パラメーター、ヘッダー、 消費するメディア型、生成するメディア型でマッピングします。
@PostMapping(
path = "/orders",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<OrderView> create(@Valid @RequestBody CreateOrder request) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(orderService.create(request));
}HandlerMethodArgumentResolver 実装は、パス変数、クエリパラメーター、ヘッダー、
Cookie、プリンシパル、Servlet オブジェクト、モデル属性、リクエストボディを提供します。
単純なテキスト値には変換とフォーマットが使われます。@ModelAttribute は
WebDataBinder を通じて名前付きプロパティをバインドします。バインディングは入力
セキュリティ境界であるため、許可フィールドを定義するか専用コマンド型を使います。
@RequestBody はメディアデコードを HttpMessageConverter に委譲します。
@Valid は Jakarta Bean Validation を適用し、@Validated は検証グループも選択できます。
モデル属性バインディングでは、バインドされた引数の直後に BindingResult パラメーター
を置くことで、コントローラーが変換エラーと検証エラーを確認できます。ローカル処理
がなければ、MVC は例外解決チェーンを通じて検証例外を変換します。
戻り値とコンテンツネゴシエーション #
HandlerMethodReturnValueHandler 実装は、ModelAndView、ビュー名、ResponseEntity、
ProblemDetail、@ResponseBody が付いたオブジェクトなどの値を処理します。レスポンス
ボディの値は HttpMessageConverter がエンコードします。
コンテンツネゴシエーションは、ハンドラーの produces 条件、リクエストが受け入れ
可能なメディア型、コンバーターの能力を比較します。サポートされない Content-Type
のリクエストボディは 415 を生成し、受け入れ可能なレスポンス表現がない場合は 406
を生成します。パス拡張子ネゴシエーションより、Accept ヘッダーと明示的なデフォルト
を優先します。
例外解決 #
HandlerExceptionResolver は失敗をモデル、ステータス、レスポンスに変換します。
標準のアノテーション設定には次が含まれます。
ExceptionHandlerExceptionResolverfor controller and@ControllerAdviceexception methods;ResponseStatusExceptionResolverfor@ResponseStatusandResponseStatusException; andDefaultHandlerExceptionResolverfor framework exceptions.
中央アドバイスは、ドメインの失敗を安定したステータスコードと一貫したエラー
スキーマへマッピングします。Spring Framework 6 は ProblemDetail と ErrorResponse
を導入しました。Spring 6.1 のドキュメントは、RFC 7807 を置き換えた RFC 9457 に
基づいて問題詳細サポートを説明しています。
スレッド、非同期リクエスト、コンテキスト #
同期 MVC 処理は Servlet コンテナースレッドで実行されます。ブロッキングするデータ ベースまたは HTTP 呼び出しは完了までそのスレッドを保持するため、コネクターから すべての下流依存関係まで、期限と容量を設定します。
コントローラーは Callable、DeferredResult、WebAsyncTask を返せます。MVC は
Servlet 非同期処理を開始し、コンテナースレッドを解放し、結果の準備ができた後に
ASYNC ディスパッチを実行します。非同期 MVC はブロッキングコードをノンブロッキング
にするのではなく、別のエグゼキューターへ作業を移します。そのエグゼキューター、
タイムアウト、キャンセル、過負荷動作を明示的に設定します。
スレッドローカルのロギング、ロケール、セキュリティ、オブザベーション状態は任意の エグゼキュータータスクへ自動的には引き継がれません。対応するインターセプターまたは タスクデコレーターを使うか、コンテキストを明示的に渡し、復元した状態を必ず消去します。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)