[解決済み] HttpURLConnectionの接続処理について教えてください。
質問内容
私は
HTTPURLConnection
を使ってウェブサービスに接続しています。私は
HTTPURLConnection
の使い方は知っていますが、それがどのように機能するのかを理解したいのです。基本的には、次のことを知りたいです。
-
どの点で
HTTPURLConnection
は与えられたURLへの接続を確立しようとしますか? - どの時点で、接続を正常に確立できたことを知ることができますか?
- 接続の確立と実際のリクエストの送信は、1つのステップ/メソッド呼び出しで行われるのでしょうか?それはどのようなメソッドですか?
-
の機能を説明できますか?
getOutputStream
とgetInputStream
を平たく言うと?私は、接続しようとしているサーバーがダウンしているときに、私が気づくのはException
でgetOutputStream
. という意味なのでしょうか?HTTPURLConnection
を呼び出したときだけ、接続を確立し始めるということでしょうか。getOutputStream
? ではgetInputStream
? でしか応答が得られないのでgetInputStream
には何もリクエストを送らなかったということでしょうか?getOutputStream
にはまだ何も送っておらず、単に接続を確立しているだけだということですか? そうするとHttpURLConnection
を呼び出したら、サーバに戻ってレスポンスを要求するのでしょうか?getInputStream
? -
ということでよろしいでしょうか?
openConnection
は単に新しい接続オブジェクトを作成するだけで、まだ接続を確立していないということでよろしいでしょうか? - 読み取りオーバーヘッドと接続オーバーヘッドを測定するにはどうすればよいですか?
どのように解決するのですか?
String message = URLEncoder.encode("my message", "UTF-8");
try {
// instantiate the URL object with the target URL of the resource to
// request
URL url = new URL("http://www.example.com/comment");
// instantiate the HttpURLConnection with the URL object - A new
// connection is opened every time by calling the openConnection
// method of the protocol handler for this URL.
// 1. This is the point where the connection is opened.
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// set connection output to true
connection.setDoOutput(true);
// instead of a GET, we're going to send using method="POST"
connection.setRequestMethod("POST");
// instantiate OutputStreamWriter using the output stream, returned
// from getOutputStream, that writes to this connection.
// 2. This is the point where you'll know if the connection was
// successfully established. If an I/O error occurs while creating
// the output stream, you'll see an IOException.
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
// write data to the connection. This is data that you are sending
// to the server
// 3. No. Sending the data is conducted here. We established the
// connection with getOutputStream
writer.write("message=" + message);
// Closes this output stream and releases any system resources
// associated with this stream. At this point, we've sent all the
// data. Only the outputStream is closed at this point, not the
// actual connection
writer.close();
// if there is a response code AND that response code is 200 OK, do
// stuff in the first if block
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// OK
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
// Server returned HTTP error code.
}
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
ご質問に対する最初の3つの回答は、上記のHTTP POSTの例で、各メソッドの横にインラインコメントとして記載されています。
から getOutputStream :
この接続に書き込む出力ストリームを返します。
基本的に、この仕組みはよく理解されていると思いますので、平易な言葉で説明し直します。
getOutputStream
は基本的に
接続
ストリームを開き、サーバにデータを書き込むことを意図しています。上記のコード例では、"message" は、投稿に残されたコメントをサーバーに送信していることになります。このとき
getOutputStream
を開くと
接続
を呼び出すまで、実際にデータを書き込むことはありません。
writer.write("message=" + message);
.
から getInputStream() :
このオープン接続から読み込む入力ストリームを返します。返された入力ストリームから読み込む際に、データが読み込めるようになる前に読み込みタイムアウトが終了した場合、SocketTimeoutExceptionがスローされることがあります。
getInputStream
はその逆を行います。例えば
getOutputStream
と同様に
接続
ストリームを開きますが、その目的はサーバーからデータを読み込むことであり、 書き込むことではありません。接続やストリームのオープンに失敗した場合は
SocketTimeoutException
.
getInputStreamはどうでしょうか?getInputStreamではレスポンスしか取得できていないので、getOutputStreamではまだ何もリクエストを送信しておらず、単に接続を確立しているだけということになるのでしょうか?
リクエストの送信とデータの送信は異なる操作であることに留意してください。リクエストの送信とデータの送信は異なる操作であることに注意してください。
getOutputStream あるいは getInputStream を呼び出すとき
url.openConnection()
接続を確立するためにサーバにリクエストを送ります。サーバーが接続が確立されたことを確認するために、ハンドシェイクが行われます。そして、その時点でデータの送受信の準備が整う。したがって、getOutputStream を呼び出す必要はありません。
<ストライク
接続を確立する
ストリームを開くために getOutputStream を呼び出す必要はありません。
平たく言えば
getInputStream
を作ることは、友達の家に電話をかけて、「ねえ、その万力棒を借りに行ってもいい?と言って握手をします。そして、その時点でつながりができ、あなたは友人の家まで歩いて行き、ドアをノックしてバイスグリップを要求し、自分の家まで歩いて帰ります。
同様の例で
getOutputStream
を使う場合、あなたの友人に電話して、「ねえ、あなたに借りているお金があるんだけど、送らせてくれないかしら?あなたの友人はお金が必要で、あなたが長い間それを保管していたことに内心うんざりしていましたが、「いいよ、来てみろよ、このケチ野郎」と言いました。そこで、あなたは友人の家まで歩いて行き、お金を彼に渡します。そして、彼はあなたを追い出し、あなたは自分の家に戻ります。
さて、素人の例の続きで、いくつかの例外を見てみましょう。友人に電話したところ留守だった場合、500 エラーが発生する可能性があります。電話をかけたら、切断された番号のメッセージが表示された場合、それは 404 ページが見つからなかったということです。もし、あなたが請求書を払わなかったために電話が使えなくなったら、それはIOExceptionの可能性があります。(注:このセクションは100%正しいとは限りません。平易な言葉で何が起こっているのかの一般的なアイデアを提供することを意図しています)。
質問その5です。
openConnectionは単に新しい接続オブジェクトを作成するだけで、接続は確立されないというのはその通りです。接続は、getInputStream または getOutputStream のいずれかを呼び出したときに確立されます。
openConnection
は新しい接続オブジェクトを作成します。から
URL.openConnection javadocs から。
:
このURLのプロトコルハンドラのopenConnectionメソッドを呼び出すことで、毎回新しい接続が開かれます。
接続はopenConnectionを呼び出したときに確立され、InputStream、OutputStream、またはその両方をインスタンス化するときに呼び出されます。
質問その6 :
オーバーヘッドを測定するために、私は一般的に、接続ブロック全体にいくつかの非常に単純なタイミングコードを以下のように巻き付けます。
long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );
// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );
リクエスト時間やオーバーヘッドを測定するためのもっと高度な方法があると思いますが、私のニーズには一般的にこれで十分です。
質問されていない、接続を閉じることに関する情報については Java では、URL 接続はいつ終了するのですか? .
関連
-
エラーが報告されました。リソースの読み込みに失敗しました:サーバーは500(内部サーバーエラー)のステータスで応答しました。
-
jd-gui Java Exceptionが発生しました。
-
JQuery DataTable 详解
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 4 at text.Division.main(Divisi
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
javaコンパイル時のエラー:不正な文字 '\ufeff' に対する解決策です。
-
HttpClientがGZIP形式でない場合の対処法
-
コミットには何も追加されないが、未追跡のファイルが存在し、gitで未追跡のファイルに対する完璧な解決策
-
[解決済み] Javaで現在のスタックトレースを取得するにはどうすればよいですか?
-
[解決済み] OutputStreamをInputStreamに変換する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
この行に複数のマーカーがある - HttpServletResponseが型エラーに解決できない
-
javaの実行中に「javaの例外が発生しました」と表示された場合はどうすればよいですか?
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
Spring Boot による HTTPS アクセスの設定
-
final, finally, finalizeの違いについて話してください。
-
SpringBootApplication を型解決できない。
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
org.glassfish.jersey.servlet.ServletContainer