143

HTTPURLConnectionWeb サービスへの接続に使用しています。使い方は知っているHTTPURLConnectionが、仕組みを理解したい。基本的に、私は次のことを知りたいです:

  • HTTPURLConnection指定された URL への接続を確立しようとするポイントはどれですか?
  • 接続が正常に確立されたことをどの時点で確認できますか?
  • 接続の確立と実際のリクエストの送信は、1 つのステップ/メソッド呼び出しで行われていますか? どんな方法ですか?
  • getOutputStreamとの機能を簡単に説明できますgetInputStreamか? 接続しようとしているサーバーがダウンしていると、Exceptionatが表示されることに気付きましたgetOutputStreamHTTPURLConnectionを呼び出したときにのみ接続の確立が開始されるということですgetOutputStreamか? はどうgetInputStreamですか?でしか応答を取得できないので、getInputStreamではまだリクエストを送信せずgetOutputStream、接続を確立しただけということですか? HttpURLConnectionを呼び出したときにサーバーに戻って応答を要求しますgetInputStreamか?
  • openConnection新しい接続オブジェクトを作成するだけで、まだ接続を確立していないと言うのは正しいですか?
  • 読み取りオーバーヘッドと接続オーバーヘッドを測定するにはどうすればよいですか?
4

5 に答える 5

196
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) {
    // ...
}

上記の HTTP POST の例では、各メソッドの横に、質問に対する最初の 3 つの回答がインライン コメントとしてリストされています。

getOutputStreamから:

この接続に書き込む出力ストリームを返します。

基本的に、これがどのように機能するかをよく理解していると思いますので、素人の言葉で繰り返します。基本的に、サーバーにデータを書き込む目的で、接続ストリームをgetOutputStream開きます。上記のコード例では、「メッセージ」は、投稿に残されたコメントを表すサーバーに送信するコメントである可能性があります。が表示されている場合、書き込み用に接続ストリームを開いていますが、実際には を呼び出すまでデータを書き込みません。getOutputStreamwriter.write("message=" + message);

getInputStream()から:

この開いている接続から読み取る入力ストリームを返します。データが読み取り可能になる前に読み取りタイムアウトが期限切れになると、返された入力ストリームからの読み取り時に SocketTimeoutException がスローされる可能性があります。

getInputStream反対を行います。と同様に、接続getOutputStreamストリームも開きますが、目的はサーバーからデータを読み取ることであり、データを書き込むことではありません。接続またはストリームの開始に失敗した場合は、.SocketTimeoutException

getInputStream はどうですか? getInputStream でしか応答を取得できないので、getOutputStream でまだリクエストを送信しておらず、単に接続を確立しているだけということですか?

リクエストの送信とデータの送信は 2 つの異なる操作であることに注意してください。getOutputStream または getInputStream を呼び出すときはurl.openConnection()、サーバーにリクエストを送信して接続を確立します。接続が確立されたことを示す確認応答をサーバーが送り返すハンドシェイクが発生します。その時点で、データを送受信する準備が整います。したがって、要求を作成する目的がデータの送信である場合を除き、ストリームを開く接続を確立するために getOutputStream を呼び出す必要はありません。

依頼するということは、平たく言えばgetInputStream、友達の家に電話して「あのバイスグリップを借りてもいいですか?」と言うようなものです。あなたの友人は、「もちろん!来て、それを手に入れてください」と言って握手を確立します。次に、その時点で接続が確立され、友人の家に歩いて行き、ドアをノックし、バイスグリップを要求し、家に戻ります.

同様の例を使用するとgetOutputStream、友人に電話して、「ねえ、私はあなたに借りているお金があります。あなたに送ってもいいですか?」と言うでしょう? あなたの友人は、お金を必要としていて、あなたが長い間それを保管していたので病気になり、「もちろん、あなたの安いろくでなしに来てください」と言います。それで、あなたは友達の家に歩いて行き、彼にお金を「POST」します。その後、彼はあなたを追い出し、あなたは家に戻ります。

さて、素人の例を続けて、いくつかの例外を見てみましょう。友人に電話したときに彼が家にいなかった場合、それは 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 接続がクローズされるのはいつですか? を参照してください。.

于 2012-04-12T04:09:35.810 に答える
18

Tim Bray は、openConnection() が実際の接続を確立しないことを述べて、簡潔なステップバイステップを提示しました。実際の HTTP 接続は、getInputStream() や getOutputStream() などのメソッドを呼び出すまで確立されません。

http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection

于 2013-07-15T23:35:57.690 に答える
3

HTTPURLConnection指定された URL への接続を確立しようとするポイントはどれですか?

URL に指定されているポートがある場合は、それ以外の場合は HTTP の場合は 80、HTTPS の場合は 443。これは文書化されていると思います。

接続が正常に確立されたことをどの時点で確認できますか?

getInputStream()または例外を取得せずに呼び出した場合getOutputStream()getResponseCode()

接続の確立と実際のリクエストの送信は、1 つのステップ/メソッド呼び出しで行われていますか? どんな方法ですか?

いいえ、ありません。

getOutputStream()との機能を簡単に説明できますgetInputStream()か?

どちらも必要に応じて最初に接続し、次に必要なストリームを返します。

接続しようとしているサーバーがダウンしていると、 で例外が発生することに気付きましたgetOutputStream()HTTPURLConnectionを呼び出したときにのみ接続の確立が開始されるということですgetOutputStream()か? はどうgetInputStream()ですか?でしか応答を取得できないので、getInputStream()ではまだリクエストを送信せずgetOutputStream()、接続を確立しただけということですか? HttpURLConnectionを呼び出したときにサーバーに戻って応答を要求しますgetInputStream()か?

上記を参照。

openConnection()新しい接続オブジェクトを作成するだけで、まだ接続を確立していないと言うのは正しいですか?

はい。

読み取りオーバーヘッドと接続オーバーヘッドを測定するにはどうすればよいですか?

接続: 時間がかかるか、戻るのに時間getInputStream()getOutputStream()かかるか、最初に電話した方。読み取り: 最初の読み取りを開始してから EOS を取得するまでの時間。

于 2013-07-15T23:45:02.380 に答える
1

HTTPURLConnection が特定の URL への接続を確立しようとするのはどの時点ですか?

明確にする価値があります。 「UrlConnection」インスタンスがあり、次に、基礎となるTcp/Ip/SSL ソケット接続、2 つの異なる概念があります。「UrlConnection」または「HttpUrlConnection」インスタンスは、単一の HTTP ページ要求と同義であり、url.openConnection() を呼び出すと作成されます。しかし、1 つの「url」インスタンスから複数の url.openConnection() を実行すると、運が良ければ、同じ Tcp/Ip ソケットと SSL ハンドシェークが再利用されます...ソケットを確立するオーバーヘッドが非常に高い SSL を使用している場合は特に有効です。

参照: HttpURLConnection の実装

于 2013-09-04T00:55:48.227 に答える