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の状態管理の使用方法の詳細な説明

推薦する

MySQLデータベースを定期的に自動バックアップする方法

データは貴重なものであることは誰もが知っています。データをバックアップしなければ、データをそのまま放...

要素ツリーコントロールは、ドロップダウンメニューとアイコンを統合します(ツリー+ドロップダウン+入力)

目次要件:実装手順:この記事では主に以下について説明します: カスタムツリーコントロール<el...

IE6 ウェブページ作成リファレンス IE6 デフォルトスタイル

これは実際には IE の公式ドキュメントではありません。他の人が実践を通じて開発した IE6 のデフ...

Vueデータ割り当て問題の解決

私が長い間遭遇してきた問題を要約してみましょう。プロジェクトでは、フロントエンドをレンダリングするた...

nginxリバースプロキシのマルチポートマッピングの実装

コードの説明1.1 http:www.baidu.test.com のデフォルトは 80 で、リバー...

Centos7 環境でソースコードから mysql5.7.16 をインストールする方法の詳細な説明

この記事では、centos7 環境でソース コードから mysql5.7.16 をインストールする方...

Nginx 仮想ホストを構成する 3 つの方法 (ドメイン名に基づく)

Nginx は、IP ベースの仮想ホスト構成、ポート ベースの仮想ホスト構成、ドメイン名ベースの仮...

Vue プロジェクトがページング効果を実現

ページング効果は、参考までにvueプロジェクトに実装されています。具体的な内容は次のとおりです。 1...

Linux でのインストール中にソフトウェア パッケージの依存関係レポートに関連する問題の解決策

目次背景1) yumのkeepchche機能を有効にする: 方法1 2) yum-utils ソフト...

Mysql systemctl start mysqld によって報告されるエラーの解決策

エラーメッセージ:制御プロセスがエラー コードで終了したため、mysqld.service のジョブ...

MySqlデータベースの基礎知識のまとめ

目次基本的なデータベース操作2) データベースを表示する3) データベースを選択する4) データベー...

IDEA が Docker を統合してリモート展開を実現するための手順

1. Dockerサーバーへのリモートアクセスを有効にするdocker が配置されているリモート サ...

Mac 向け MySQL のインストールと設定のチュートリアル

この記事では、MacでのMySQLインストールチュートリアルを参考までに紹介します。具体的な内容は次...

Vue で jsx 構文を正しく使用する方法

目次序文仮想DOM仮想DOMとは仮想DOMの利点レンダリング関数とは何ですか? jsx Vue3 で...

vue-video-player でのブレークポイント再開の実装

最近のプロジェクトでは、ブレークポイントからビデオの再生を再開する機能を実装する必要がありました。こ...