Tomcat が応答データグラムを書き戻すタイミングの詳細な分析

Tomcat が応答データグラムを書き戻すタイミングの詳細な分析

疑問が生じる

この質問は、ファイルのダウンロードを記述しているときに発生しました。HttpServletResponse を使用して Outputstream を取得し、OutputStream を使用してデータを直接書き込みました。その時、この OutputStream が対応する Socket 接続の OutputStream であるかどうか疑問に思いました。つまり、プログラムがストリームを使用して書き込んでいるときに、データも送信されているということですか?

レスポンスの OutputStream はデータをどこに書き込みますか?

そこで、HttpServletResponse の getOutputStream メソッドを見て、そのコメントが何と言っているかを確認しました。

/**
  * バイナリの書き込みに適した{@link ServletOutputStream}を返します 
  * レスポンス内のデータ。サーブレットコンテナは、
  * バイナリデータ。 
  *
  * <p> ServletOutputStream で flush() を呼び出すと、応答がコミットされます。
  *
  * このメソッドまたは{@link #getWriter}のいずれかが 
  * {@link #reset} の場合を除き、本体を書き込むために呼び出され、両方を書き込むために呼び出されることはありません。
  * が呼び出されました。
  *
  * @return バイナリデータを書き込むための {@link ServletOutputStream} 
  *
  * @exception IllegalStateException、<code>getWriter</code> メソッドの場合
  * この応答で呼び出されました
  *
  * @exception IOException 入力または出力例外が発生した場合
  *
  * @see #getWriter
  * @see #リセット
  */
 public ServletOutputStream getOutputStream() は IOException をスローします。

上記のコメントでは、OutputStream はレスポンス本文のコンテンツを書き込むために使用されると述べられており、また flush() メソッドについても言及されています。これは、バッファリングが必要であることを意味するため、データを書き込むためにソケット上で直接操作すべきではないことを意味します。一時的な保存用のバイト配列を用意し、それを均一にフラッシュする必要があると思います。しかし、まだ確信が持てなかったので、Tomcat のソース コードを調べてみました。

ServletOutputStream の実装クラス、CoyoteOuputStream を見つけます。 OutputStream の抽象メソッド write を実装し、データを OutputBuffer 型のフィールドに書き込んで保存します。この OutputBuffer オブジェクトは coyote/Response から取得されます。実際、この OutputBuffer は単なるインターフェースであり、具体的な実装は StreamOutputBuffer です。データ サイズに制限はありません。リンク リストに格納され、各リンク リスト ノードには 8196 バイトが格納されます。

応答データグラムはいつクライアントに返されますか?

実際には、OutputBuffer の flush メソッドを呼び出すときにチェックします。レイヤーごとに調べて、最終的に connector/Response の finishResponse() メソッドを見つけました。このメソッドは、最初に応答行と応答ヘッダーを送信します。次に、応答本文を送信します。 Tomcat のソース コードをあまり読んでいませんが、HTTP リクエストの処理を説明する優れたシーケンス図がここにあります。以下では、サーブレットの service メソッド呼び出しと Response の FinishResponse メソッド呼び出しに焦点を当てます。サービス メソッドが返された後、finishResponse 操作が実行されることが分かります。つまり、サーブレット プログラムが要求を処理すると、Tomcat は応答をクライアントに返します。

注:サーブレットプログラムは、基礎となるデータの送受信には関与せず、また制御も行いません。

図の中でサーブレットのサービス メソッドが呼び出される場所はどこですか?

ApplicationFilterChain の internalDoFilter メソッドに含まれます。

サーブレット プログラムの処理要求とはどういう意味ですか?

基本的に、サーブレット プログラムの仕事は、リクエスト情報に基づいてレスポンス情報を入力することです。

サーブレット プログラムと Spring MVC の関係は何ですか?

Spring MVC の基盤となるレイヤーは依然として Serlvet であり、DispatcherServlet と呼ばれるサーブレットを使用してすべてのリクエストを処理し、次にリクエストを対応する @RequestMapping アノテーション付きメソッドに分散して処理します。一般的に言えば、サービス メソッドの呼び出しを完了します。

では、MVC リターン ページと REST データの戻りはどうでしょうか?

ページを返すということは、ページ データをレスポンス ボディに書き込むことを意味します。@ResponseBody アノテーションは、実際には @RequestMapping でアノテーションが付けられたメソッドの戻り値を JSON 文字列に変換し、レスポンス ボディに書き込みます。ここでの応答 Body は、上記の OutputBuffer を参照します。

Tomcat と Servlet プログラムの役割

「Tomcat の仕組み」では、サーブレット コンテナ (Tomcat はサーブレット コンテナです) のタスクは次のように要約できると説明されています。

1. リクエスト オブジェクトを作成し、関連情報 (パラメーター、ヘッダー、Cookie、URI など) を入力します。

2. レスポンスオブジェクトを作成する

3. このリクエストに関連付けられたサーブレットのサービス メソッドを呼び出し、リクエストとレスポンスを渡します。

ここで、私自身の言葉で説明します。ブラウザがサーバーにリクエストを送信すると、サーバーはリクエスト データグラムの内容を解析し、リクエスト情報で満たされたリクエスト オブジェクトを作成し、「空の」レスポンス オブジェクトを作成します。次に、これらの 2 つのオブジェクトがサーブレットのサービス メソッドに渡され、レスポンス オブジェクトへの入力が完了し、レスポンス データがクライアントに送信されます。

なぜ Request オブジェクトを渡す必要があるのでしょうか?

Request オブジェクトを渡さない場合、Servlet プログラムは何を入力すればよいかわかりません。つまり、どのようなリソースが必要なのかがわかりません。

Tomcat はリクエストに関連付けられたサーブレットをどのように見つけるのでしょうか?

Tomcat を開発する場合、どのプロジェクトを Tomcat にデプロイするか、またはサーブレット プログラムが何と呼ばれるかを知ることは不可能であることはわかっています。したがって、サービス メソッドを呼び出すためのハード コーディングは不可能であり、リフレクション メカニズムが使用されます。

Spring Boot フレームワークを使用する前にプロジェクトをどのようにデプロイしたか考えてみましょう。プロジェクトをパッケージ化して、Tomcat の webapp ディレクトリに配置するだけです。実行後、プロジェクトに対応する URL は localhost:8080/projectName/xxx になりますか?また、プロジェクトでは、アノテーション スタイルか web.xml スタイルかを問わず、サーブレット プログラムのマッピングが構成されます。 URL を Servlet クラス ファイルにマップします。

リクエストが来ると、まずprojectNameに従って対応するプロジェクトを見つけ、その後のURLに従って対応するServletクラス名にマッピングします。その後、Tomcat はリフレクション メカニズムを使用して Servlet クラス ファイルをロードし、インスタンスを取得して、サービス メソッドを呼び出します。

coyote/Response、connector/Response、connector/ResponseFacade の関係は何ですか?

coyote/Response は主に基礎となるデータ転送にリンクされており、connector/Response は HttpServletResponse インターフェースを実装する coyote/Response の上位レベルのラッパーです。ただし、サービス メソッドに直接渡されると、ユーザーが HttpServletResponse を connector/Response に直接変換し、いくつかの基礎となるメソッドを直接呼び出す恐れがあります。したがって、HttpServletResponse インターフェースで定義されているものを除く、コネクタ/レスポンスのすべてのパブリック メソッドをブロックする「ファサード モード」が導入されています。つまり、サービスに渡されるのは実際にはコネクタ/ResponseFacade オブジェクトであり、強制的に実際の型に変換しても、HttpServletResponse インターフェースで定義されたメソッドしか見えません。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • 動的データと静的リソースのリクエストを分離するための Nginx + Tomcat の詳細な説明
  • Linux 上の Tomcat で MySQL にデータを挿入するときに中国語の文字化けが発生する問題を解決する
  • Tomcat データ ソースの原理、構成、使用方法の紹介
  • Android は Apache Tomcat サーバー (MySql データベース) とのデータ相互作用を実装します。
  • Tomcat 7-dbcp 構成データベース接続プールの詳細な説明
  • Post メソッドを使用して Tomcat サーバーにデータを送信する方法
  • Get メソッドを使用して Tomcat サーバーにデータを送信する方法
  • 接続プールを使用してTomcatサーバーのOracleデータベースに接続する
  • Tomcatc3p0 で jnid データ ソースを構成する 2 つの実装方法の分析

<<:  1つのSQL文でMySQLの重複排除が完了し、1つが保持されます。

>>:  Vue3の状態管理の使用方法の詳細な説明

推薦する

HTML テーブル マークアップ チュートリアル (5): ライト ボーダー カラー属性 BORDERCOLORLIGHT

表では、左上の境界線の色を個別に定義したり、セルの右下の境界線の色を定義したりできます。これら 2 ...

この記事ではCSSボーダーの使い方を説明します

境界線のスタイルborder-style プロパティは、表示する境界線の種類を指定します。 bord...

JSON.stringify を使用する際に発生する循環参照の問題を解決する方法の詳細な説明

プログラマーが日常的に TypeScript/JavaScript 開発を行う場合、複雑な Java...

FirefoxのWeb開発者を使用してWebページのスタイルを無効にする方法

前提条件: Web開発者プラグインがインストールされている操作手順: [ツール] -> [We...

1つの記事でJavaScriptのクロージャ関数について学ぶ

目次変数のスコープ閉鎖の概念クロージャの使用クロージャのデメリット最後に、クロージャのメリットとデメ...

LinuxシステムにISOファイルをインストールする方法

Linux システムで iso ファイルをインストールするにはどうすればいいですか?インストール手順...

Linuxで環境変数を削除する詳細な手順

Linuxで環境変数を削除するには?unsetコマンドを使用してすぐに削除します1. Linuxクラ...

VirtualBox での CentOS 8.1 仮想マシンのインストールを最小限に抑える詳細なチュートリアル

1. 関連ツールと画像をダウンロードするダウンロードリンクバーチャルボックス: https://do...

Dockerを使用してPythonランタイム環境の基本イメージを作成する方法

1. 準備1.1 Pythonインストールパッケージをダウンロードします(注:Pythonバージョン...

React で複数の setStates が何回呼び出されるのでしょうか?

目次1. 2 つの setState を何回呼び出すのですか? 2. 2 つの setState の...

MySQL エンコーディング utf8 および utf8mb4 utf8mb4_unicode_ci および utf8mb4_general_ci

参考: MySQL 文字セットの概要utf8mb4 は MySQL 8.0 のデフォルトの文字セット...

HTML チュートリアル: よく使われる HTML タグのコレクション (4)

導入された HTML タグは、必ずしも XHTML 仕様に完全に準拠しているわけではありません。実際...

XHTML CSS ページをプリンタ ページに変換する

以前は、Web ページのプリンタ対応バージョンを作成するには、印刷したときに見栄えがよくなるようにレ...

純粋なHTML+CSSでタイピング効果を実現

この記事は主に、一定の参考値を持つ純粋な HTML + CSS によって実現されるタイピング効果を紹...

Docker Docker の保存場所を変更する コンテナイメージのサイズ制限を変更する操作

これは新しいバージョンではもう不可能なようで、推奨されません。そうでない場合は、ソフト リンクを直接...