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 の rel 属性の分析

.y { background: url(//img.jbzj.com/images/o_y.pn...

フレックスマルチカラムレイアウトで発生する問題と解決策の詳細な説明

フレックス レイアウトは間違いなくシンプルで使いやすいです。レイアウトをよりシンプルかつ高速にします...

CentOS7 環境で gcc (バージョン 10.2.0) をアップグレードする詳細な手順

目次簡単な紹介1. 現在のgccバージョンを確認する2. gccインストールパッケージ(バージョン1...

MySQL の繰り返し読み取りレベルでファントム読み取りを解決できますか?

導入データベース理論についてさらに学んでいくうちに、さまざまな分離レベルによって起こり得る問題につい...

JavaScript でドラッグ スライダー パズルの検証機能を実装します (html5、canvas)

導入:スライダー ドラッグ検証は現在、多くの場所で使用されています。週末に 1 つ作成しようと思い、...

MySQLにおけるテーブルインデックスの定義方法と導入

概要インデックスは、テーブル内の 1 つ以上の列に基づいて DBMS によって特定の順序で作成される...

Ubuntu仮想マシンでシリアル通信にcutecomを使用する方法

Ubuntu仮想マシンでのシリアル通信にcutecomを使用する1. cutecomをインストールす...

Dockerイメージのサイズを縮小する6つの方法

2017 年に Vulhub に取り組み始めてから、私は厄介な問題に悩まされてきました。Docker...

SSMは、mysqlデータベースアカウントのパスワード暗号文ログイン機能を実装します。

導入当社は、情報セキュリティと機密アプリケーションに関わるいくつかのプロジェクトの研究開発に従事して...

BootStrap グリッド間に隙間を残す解決策

目次[例を見る]: 【本来の効果は以下の通り】理由は次のとおりです。 【解決】:要約するBootSt...

JavaScript Sandboxについての簡単な説明

序文:サンドボックスといえば、私たちの頭には反射的に上の写真が思い浮かび、すぐに興味がわいてくるかも...

VMware15 centos7 ブリッジモード ssh に突然アクセスできなくなる問題を解決する

仮想マシンに独自の LAN IP を持たせたいので、テストを容易にするためにブリッジを使用します。 ...

DockerでMongoDBコンテナをデプロイする方法

目次Dockerとは展開する1. イメージをプルする2. 画像を表示する3. コンテナを実行する4....

Docker プルタイムアウトの解決策

最近、Docker イメージのプルが非常に不安定です。遅く、タイムアウトすることがよくあります。 x...

同じレベルの要素で Position:fixed と margin-top を一緒に使用する場合の CSS の問題

問題の説明CSS を使用して上部の固定効果を実現したいと思います。 margin-top と pos...