Spring MVC

最終更新: 2023-11-03 17:36:24 +0800 +0800
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

Spring MVC は Spring Framework の Servlet ベース Web フレームワークです。フロント コントローラーである DispatcherServlet は、リクエストマッピング、引数解決、 コントローラー呼び出し、戻り値処理、例外変換を調整します。Spring WebFlux は異なる リアクティブランタイムとスレッドモデルを使用するため、両フレームワークを交換可能 なものとして扱ってはなりません。

ブートストラップとディスパッチ #

Boot ではない Servlet アプリケーションは、WebApplicationInitializer を通じて Web アプリケーションコンテキストとディスパッチャーを登録できます。

java
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 の特別な処理を維持 できます。/* ではそれらのディスパッチも捕捉します。

各リクエストで、ディスパッチャーは次を行います。

  1. 順序付けられた HandlerMapping 実装にハンドラーとインターセプターを要求する。
  2. そのハンドラーを呼び出せる HandlerAdapter を選択する。
  3. pre-handle インターセプターとハンドラーを呼び出す。
  4. 戻り値をレスポンスボディ、ビュー、非同期結果、その他の対応形式として処理する。
  5. 例外リゾルバーと完了インターセプターを実行する。

MVC の戦略オブジェクトはディスパッチャーコンテキストの Bean です。 @EnableWebMvc は通常の Spring アプリケーション向け標準設定をインポートします。 Spring Boot では、自動設定を完全に引き取る @EnableWebMvc を追加する代わりに、 WebMvcConfigurer を実装して Boot の設定を拡張します。

リクエストマッピング、バインディング、検証 #

アノテーション付きコントローラーは、パス、HTTP メソッド、パラメーター、ヘッダー、 消費するメディア型、生成するメディア型でマッピングします。

java
@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 は失敗をモデル、ステータス、レスポンスに変換します。 標準のアノテーション設定には次が含まれます。

  • ExceptionHandlerExceptionResolver for controller and @ControllerAdvice exception methods;
  • ResponseStatusExceptionResolver for @ResponseStatus and ResponseStatusException; and
  • DefaultHandlerExceptionResolver for framework exceptions.

中央アドバイスは、ドメインの失敗を安定したステータスコードと一貫したエラー スキーマへマッピングします。Spring Framework 6 は ProblemDetail と ErrorResponse を導入しました。Spring 6.1 のドキュメントは、RFC 7807 を置き換えた RFC 9457 に 基づいて問題詳細サポートを説明しています。

スレッド、非同期リクエスト、コンテキスト #

同期 MVC 処理は Servlet コンテナースレッドで実行されます。ブロッキングするデータ ベースまたは HTTP 呼び出しは完了までそのスレッドを保持するため、コネクターから すべての下流依存関係まで、期限と容量を設定します。

コントローラーは Callable、DeferredResult、WebAsyncTask を返せます。MVC は Servlet 非同期処理を開始し、コンテナースレッドを解放し、結果の準備ができた後に ASYNC ディスパッチを実行します。非同期 MVC はブロッキングコードをノンブロッキング にするのではなく、別のエグゼキューターへ作業を移します。そのエグゼキューター、 タイムアウト、キャンセル、過負荷動作を明示的に設定します。

スレッドローカルのロギング、ロケール、セキュリティ、オブザベーション状態は任意の エグゼキュータータスクへ自動的には引き継がれません。対応するインターセプターまたは タスクデコレーターを使うか、コンテキストを明示的に渡し、復元した状態を必ず消去します。

Primary References #

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)