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 câu trả lời đầu tiên cho câu hỏi của bạn được liệt kê dưới dạng nhận xét nội tuyến, bên cạnh mỗi phương thức, trong ví dụ HTTP POST ở trên.
Từ getOutputStream :
Trả về một luồng đầu ra ghi vào kết nối này.
Về cơ bản, tôi nghĩ rằng bạn hiểu rõ về cách thức hoạt động của nó, vì vậy hãy để tôi nhắc lại trong các điều khoản của giáo dân. getOutputStream
về cơ bản sẽ mở ra một luồng kết nối , với ý định ghi dữ liệu lên máy chủ. Trong ví dụ mã ở trên, "tin nhắn" có thể là một bình luận mà chúng tôi đang gửi đến máy chủ đại diện cho một bình luận để lại trên một bài đăng. Khi bạn thấy getOutputStream
, bạn đang mở luồng kết nối để viết, nhưng thực tế bạn không viết bất kỳ dữ liệu nào cho đến khi bạn gọi writer.write("message=" + message);
.
Từ getInputStream () :
Trả về một luồng đầu vào đọc từ kết nối mở này. Có thể ném một SocketTimeoutException khi đọc từ luồng đầu vào được trả về nếu hết thời gian đọc trước khi dữ liệu có sẵn để đọc.
getInputStream
làm ngược lại. Giống như getOutputStream
, nó cũng mở một luồng kết nối , nhưng mục đích là đọc dữ liệu từ máy chủ, không ghi vào nó. Nếu kết nối hoặc mở luồng không thành công, bạn sẽ thấy a SocketTimeoutException
.
Làm thế nào về getInputStream? Vì tôi chỉ có thể nhận được phản hồi tại getInputStream, nên điều đó có nghĩa là tôi chưa gửi bất kỳ yêu cầu nào tại getOutputStream mà chỉ thiết lập kết nối?
Hãy nhớ rằng gửi yêu cầu và gửi dữ liệu là hai hoạt động khác nhau. Khi bạn gọi getOutputStream hoặc getInputStream url.openConnection()
, bạn gửi yêu cầu đến máy chủ để thiết lập kết nối. Có một cái bắt tay xảy ra trong đó máy chủ gửi lại một xác nhận cho bạn rằng kết nối được thiết lập. Đó là lúc bạn chuẩn bị gửi hoặc nhận dữ liệu. Do đó, bạn không cần gọi getOutputStream để thiết lập kết nối mở một luồng, trừ khi mục đích của bạn để thực hiện yêu cầu là gửi dữ liệu.
Theo cách nói của giáo dân, làm cho một getInputStream
yêu cầu tương đương với việc gọi điện thoại đến nhà bạn của bạn để nói "Này, có ổn không nếu tôi ghé qua và mượn cặp phó kẹp đó?" và bạn của bạn thiết lập cái bắt tay bằng cách nói, "Chắc chắn! Hãy đến và lấy nó". Sau đó, tại thời điểm đó, kết nối được thực hiện, bạn đi bộ đến nhà của bạn mình, gõ cửa, yêu cầu các phó kẹp và quay trở lại nhà của bạn.
Sử dụng một ví dụ tương tự getOutputStream
sẽ liên quan đến việc gọi cho bạn của bạn và nói "Này, tôi có số tiền đó tôi nợ bạn, tôi có thể gửi nó cho bạn không"? Bạn của bạn, cần tiền và bệnh tật bên trong mà bạn đã giữ nó quá lâu, nói "Chắc chắn, đến với bạn khốn rẻ tiền". Vì vậy, bạn đi bộ đến nhà của bạn bè của bạn và "ĐĂNG" tiền cho anh ta. Sau đó anh ta đuổi bạn ra ngoài và bạn trở về nhà.
Bây giờ, tiếp tục với ví dụ của giáo dân, chúng ta hãy xem xét một số Ngoại lệ. Nếu bạn gọi cho bạn của bạn và anh ấy không ở nhà, đó có thể là một lỗi 500. Nếu bạn gọi và nhận được một tin nhắn số bị ngắt kết nối vì bạn của bạn mệt mỏi vì bạn vay tiền mọi lúc, đó không phải là trang 404. Nếu điện thoại của bạn chết vì bạn không thanh toán hóa đơn, đó có thể là IOException. (LƯU Ý: Phần này có thể không chính xác 100%. Nó nhằm cung cấp cho bạn ý tưởng chung về những gì đang xảy ra trong các điều khoản của giáo dân.)
Câu hỏi số 5:
Đúng, bạn đúng rằng openConnection chỉ đơn giản là tạo một đối tượng kết nối mới nhưng không thiết lập nó. Kết nối được thiết lập khi bạn gọi getInputStream hoặc getOutputStream.
openConnection
tạo một đối tượng kết nối mới. Từ URL.openConnection javadocs :
Một kết nối mới được mở mỗi lần bằng cách gọi phương thức openConnection của trình xử lý giao thức cho URL này.
Kết nối được thiết lập khi bạn gọi openConnection và InputStream, OutputStream hoặc cả hai, được gọi khi bạn khởi tạo chúng.
Câu hỏi số 6 :
Để đo chi phí, tôi thường bọc một số mã thời gian rất đơn giản xung quanh toàn bộ khối kết nối, như vậy:
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) );
Tôi chắc chắn có nhiều phương pháp nâng cao hơn để đo thời gian và chi phí yêu cầu, nhưng điều này thường đủ cho nhu cầu của tôi.
Để biết thông tin về việc đóng các kết nối mà bạn không hỏi về, hãy xem trong Java khi nào kết nối URL đóng? .