String message = URLEncoder.encode("my message", "UTF-8");
try {
URL url = new URL("http://www.example.com/comment");
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
writer.write("message=" + message);
writer.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
} else {
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
3 jawaban pertama atas pertanyaan Anda terdaftar sebagai komentar sebaris, di samping setiap metode, dalam contoh HTTP POST di atas.
Dari getOutputStream :
Mengembalikan aliran keluaran yang menulis ke koneksi ini.
Pada dasarnya, saya pikir Anda memiliki pemahaman yang baik tentang cara kerjanya, jadi izinkan saya mengulanginya dalam istilah awam. getOutputStream
pada dasarnya membuka aliran koneksi , dengan tujuan menulis data ke server. Dalam contoh kode di atas, "pesan" bisa menjadi komentar yang kita kirim ke server yang mewakili komentar yang ditinggalkan pada sebuah posting. Saat Anda melihat getOutputStream
, Anda membuka aliran koneksi untuk menulis, tetapi Anda tidak benar-benar menulis data apa pun hingga Anda menelepon writer.write("message=" + message);
.
Dari getInputStream () :
Mengembalikan aliran input yang membaca dari koneksi terbuka ini. SocketTimeoutException dapat dilemparkan saat membaca dari aliran input yang dikembalikan jika batas waktu baca kedaluwarsa sebelum data tersedia untuk dibaca.
getInputStream
melakukan sebaliknya. Seperti getOutputStream
, ini juga membuka aliran koneksi , tetapi tujuannya adalah untuk membaca data dari server, bukan menulis ke sana. Jika koneksi atau pembukaan aliran gagal, Anda akan melihat file SocketTimeoutException
.
Bagaimana dengan getInputStream? Karena saya hanya bisa mendapatkan respons di getInputStream, apakah itu berarti saya belum mengirim permintaan apa pun di getOutputStream tetapi hanya membuat koneksi?
Perlu diingat bahwa mengirim permintaan dan mengirim data adalah dua operasi yang berbeda. Saat Anda menjalankan getOutputStream atau getInputStream url.openConnection()
, Anda mengirim permintaan ke server untuk membuat sambungan. Ada jabat tangan yang terjadi di mana server mengirimkan kembali pengakuan kepada Anda bahwa koneksi dibuat. Pada saat itulah Anda siap untuk mengirim atau menerima data. Jadi, Anda tidak perlu memanggil getOutputStream untuk membuat koneksi membuka aliran, kecuali tujuan Anda membuat permintaan adalah untuk mengirim data.
Dalam istilah awam, mengajukan getInputStream
permintaan sama dengan menelepon ke rumah teman Anda untuk mengatakan "Hei, bolehkah saya datang dan meminjam sepasang wakil pegangan itu?" dan teman Anda menjalin jabat tangan dengan mengatakan, "Tentu! Datang dan dapatkan". Kemudian, pada titik itu, koneksi dibuat, Anda berjalan ke rumah teman Anda, mengetuk pintu, meminta wakil pegangan, dan berjalan kembali ke rumah Anda.
Menggunakan contoh serupa untuk getOutputStream
akan melibatkan menelepon teman Anda dan berkata "Hei, saya punya uang yang saya berutang kepada Anda, dapatkah saya mengirimkannya kepada Anda"? Teman Anda, yang membutuhkan uang dan sakit hati karena Anda menyimpannya begitu lama, berkata "Tentu, ayolah bajingan murahan". Jadi, Anda berjalan ke rumah teman Anda dan "POSTING" uang itu kepadanya. Dia kemudian menendang Anda keluar dan Anda berjalan kembali ke rumah Anda.
Sekarang, lanjutkan dengan contoh orang awam, mari kita lihat beberapa Pengecualian. Jika Anda menelepon teman Anda dan dia tidak ada di rumah, itu mungkin kesalahan 500. Jika Anda menelepon dan mendapat pesan nomor terputus karena teman Anda bosan dengan Anda meminjam uang sepanjang waktu, halaman 404 itu tidak ditemukan. Jika ponsel Anda mati karena Anda tidak membayar tagihan, itu bisa menjadi IOException. (CATATAN: Bagian ini mungkin tidak 100% benar. Ini dimaksudkan untuk memberi Anda gambaran umum tentang apa yang terjadi dalam istilah awam.)
Pertanyaan # 5:
Ya, Anda benar bahwa openConnection hanya membuat objek koneksi baru tetapi tidak membuatnya. Koneksi dibuat saat Anda memanggil getInputStream atau getOutputStream.
openConnection
membuat objek koneksi baru. Dari javadocs URL.openConnection :
Koneksi baru dibuka setiap kali dengan memanggil metode openConnection dari penangan protokol untuk URL ini.
Koneksi dibuat saat Anda memanggil openConnection, dan InputStream, OutputStream, atau keduanya, dipanggil saat Anda membuat instance-nya.
Pertanyaan # 6 :
Untuk mengukur overhead, saya biasanya membungkus beberapa kode waktu yang sangat sederhana di seluruh blok koneksi, seperti:
long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );
Saya yakin ada metode yang lebih canggih untuk mengukur waktu permintaan dan overhead, tetapi ini umumnya cukup untuk kebutuhan saya.
Untuk informasi tentang menutup koneksi, yang tidak Anda tanyakan, lihat Di Java kapan koneksi URL ditutup? .
Returns an output stream that writes to this connection.
danReturns an input stream that reads from this open connection.
. Arus keluaran dan arus masukan terpisah dari koneksi.Tim Bray menyajikan langkah demi langkah yang ringkas, menyatakan bahwa openConnection () tidak membuat koneksi yang sebenarnya. Sebaliknya, koneksi HTTP sebenarnya tidak dibuat sampai Anda memanggil metode seperti getInputStream () atau getOutputStream ().
http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection
sumber
Di porta yang disebutkan di URL jika ada, jika tidak 80 untuk HTTP dan 443 untuk HTTPS. Saya yakin ini didokumentasikan.
Saat Anda memanggil getInputStream () atau getOutputStream () atau getResponseCode () tanpa mendapatkan pengecualian.
Tidak dan tidak ada.
Salah satunya terhubung terlebih dahulu jika perlu, lalu mengembalikan streaming yang diperlukan.
Lihat di atas.
Iya.
Connect: luangkan waktu yang diperlukan getInoutStream () atau getOutputStream () untuk kembali, mana saja yang Anda panggil terlebih dahulu. Baca: waktu dari mulai membaca pertama hingga mendapatkan EOS.
sumber
Pada titik manakah HTTPURLConnection mencoba membuat sambungan ke URL yang diberikan?
Perlu diklarifikasi, ada contoh 'UrlConnection' dan kemudian ada koneksi soket Tcp / Ip / SSL yang mendasari , 2 konsep berbeda. Instance 'UrlConnection' atau 'HttpUrlConnection' sama dengan satu permintaan halaman HTTP, dan dibuat saat Anda memanggil url.openConnection (). Tetapi jika Anda melakukan beberapa url.openConnection () dari satu contoh 'url' maka jika Anda beruntung, mereka akan menggunakan kembali soket Tcp / Ip yang sama dan hal-hal handshaking SSL ... yang bagus jika Anda melakukan banyak permintaan halaman ke server yang sama, terutama jika Anda menggunakan SSL di mana biaya pembuatan soket sangat tinggi.
Lihat: Implementasi HttpURLConnection
sumber
Saya menjalani latihan untuk menangkap pertukaran paket tingkat rendah, dan menemukan bahwa koneksi jaringan hanya dipicu oleh operasi seperti getInputStream, getOutputStream, getResponseCode, getResponseMessage, dll.
Berikut adalah pertukaran paket yang ditangkap ketika saya mencoba menulis program kecil untuk mengunggah file ke Dropbox.
Di bawah ini adalah program mainan dan penjelasan saya
/* Create a connection LOCAL object, * the openConnection() function DOES NOT initiate * any packet exchange with the remote server. * * The configurations only setup the LOCAL * connection object properties. */ HttpURLConnection connection = (HttpURLConnection) dst.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); ...//headers setup byte[] testContent = {0x32, 0x32}; /** * This triggers packet exchange with the remote * server to create a link. But writing/flushing * to a output stream does not send out any data. * * Payload are buffered locally. */ try (BufferedOutputStream outputStream = new BufferedOutputStream(connection.getOutputStream())) { outputStream.write(testContent); outputStream.flush(); } /** * Trigger payload sending to the server. * Client get ALL responses (including response code, * message, and content payload) */ int responseCode = connection.getResponseCode(); System.out.println(responseCode); /* Here no further exchange happens with remote server, since * the input stream content has already been buffered * in previous step */ try (InputStream is = connection.getInputStream()) { Scanner scanner = new Scanner(is); StringBuilder stringBuilder = new StringBuilder(); while (scanner.hasNextLine()) { stringBuilder.append(scanner.nextLine()).append(System.lineSeparator()); } } /** * Trigger the disconnection from the server. */ String responsemsg = connection.getResponseMessage(); System.out.println(responsemsg); connection.disconnect();
sumber