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 ข้อแรกสำหรับคำถามของคุณจะแสดงเป็นความคิดเห็นแบบอินไลน์ข้างแต่ละวิธีในตัวอย่าง HTTP POST ด้านบน
จากgetOutputStream :
ส่งคืนเอาต์พุตสตรีมที่เขียนไปยังการเชื่อมต่อนี้
โดยพื้นฐานแล้วฉันคิดว่าคุณมีความเข้าใจดีเกี่ยวกับวิธีการทำงานดังนั้นขอฉันย้ำอีกครั้งในแง่ของคนธรรมดา getOutputStream
โดยทั่วไปจะเปิดสตรีมการเชื่อมต่อโดยมีจุดประสงค์เพื่อเขียนข้อมูลไปยังเซิร์ฟเวอร์ ในตัวอย่างโค้ดด้านบน "ข้อความ" อาจเป็นความคิดเห็นที่เราส่งไปยังเซิร์ฟเวอร์ซึ่งแสดงถึงความคิดเห็นที่ทิ้งไว้ในโพสต์ เมื่อคุณเห็นgetOutputStream
ว่าคุณกำลังเปิดการเชื่อมต่อกระแสสำหรับการเขียน แต่คุณไม่จริงเขียนข้อมูลใด ๆ writer.write("message=" + message);
จนกว่าคุณเรียก
จากgetInputStream () :
ส่งคืนอินพุตสตรีมที่อ่านจากการเชื่อมต่อแบบเปิดนี้ SocketTimeoutException สามารถโยนได้เมื่ออ่านจากสตรีมอินพุตที่ส่งคืนหากหมดเวลาการอ่านก่อนที่ข้อมูลจะพร้อมสำหรับการอ่าน
getInputStream
ตรงกันข้าม เช่นเดียวกับgetOutputStream
มันยังเปิดสตรีมการเชื่อมต่อแต่มีจุดประสงค์เพื่ออ่านข้อมูลจากเซิร์ฟเวอร์ไม่ใช่เขียนลงไป หากการเชื่อมต่อหรือการเปิดสตรีมล้มเหลวคุณจะเห็นไฟล์SocketTimeoutException
.
แล้ว getInputStream ล่ะ? เนื่องจากฉันสามารถรับคำตอบได้ที่ getInputStream นั่นหมายความว่าฉันยังไม่ได้ส่งคำขอใด ๆ ที่ getOutputStream แต่เพียงแค่สร้างการเชื่อมต่อ
โปรดทราบว่าการส่งคำขอและการส่งข้อมูลเป็นการดำเนินการสองอย่างที่แตกต่างกัน เมื่อคุณเรียกใช้getOutputStream หรือ getInputStream url.openConnection()
คุณจะส่งคำร้องขอไปยังเซิร์ฟเวอร์เพื่อสร้างการเชื่อมต่อ มีการจับมือเกิดขึ้นโดยที่เซิร์ฟเวอร์ส่งการตอบรับกลับมาให้คุณทราบว่ามีการเชื่อมต่อแล้ว เมื่อถึงเวลานั้นคุณก็พร้อมที่จะส่งหรือรับข้อมูล ดังนั้นคุณไม่จำเป็นต้องเรียกใช้ getOutputStream เพื่อสร้างการเชื่อมต่อเพื่อเปิดสตรีมเว้นแต่จุดประสงค์ของคุณในการส่งคำขอคือการส่งข้อมูล
ในแง่ของคนธรรมดาการgetInputStream
ร้องขอจะเทียบเท่ากับการโทรศัพท์ไปบ้านเพื่อนเพื่อบอกว่า "เฮ้ฉันจะมาขอยืมตัวรองคู่นั้นได้ไหม" และเพื่อนของคุณก็เริ่มจับมือกันโดยพูดว่า "ได้สิมารับสิ" จากนั้นเมื่อถึงจุดนั้นคุณก็เดินไปที่บ้านของเพื่อนเคาะประตูขอที่รองจับแล้วเดินกลับไปที่บ้านของคุณ
การใช้ตัวอย่างที่คล้ายกันเพื่อgetOutputStream
โทรหาเพื่อนของคุณและพูดว่า "เฮ้ฉันมีเงินเป็นหนี้คุณฉันจะส่งให้คุณได้ไหม" เพื่อนของคุณต้องการเงินและป่วยอยู่ข้างในที่คุณเก็บมันมานานบอกว่า "ได้สิมาหาไอ้เลว" คุณจึงเดินไปที่บ้านของเพื่อนและ "โพสต์" เงินให้เขา จากนั้นเขาก็ไล่คุณออกและคุณก็เดินกลับไปที่บ้านของคุณ
ตอนนี้ดำเนินการต่อด้วยตัวอย่างของฆราวาสมาดูข้อยกเว้นบางประการ ถ้าคุณโทรหาเพื่อนแล้วเขาไม่อยู่บ้านนั่นอาจเป็นข้อผิดพลาด 500 หากคุณโทรหาและได้รับข้อความหมายเลขที่ถูกตัดการเชื่อมต่อเนื่องจากเพื่อนของคุณเบื่อที่คุณจะยืมเงินตลอดเวลานั่นคือหน้า 404 ไม่พบ หากโทรศัพท์ของคุณเสียเพราะคุณไม่ได้จ่ายบิลนั่นอาจเป็น IOException (หมายเหตุ: ส่วนนี้อาจไม่ถูกต้อง 100% มีจุดมุ่งหมายเพื่อให้คุณทราบโดยทั่วไปว่าเกิดอะไรขึ้นในแง่ของคนธรรมดา)
คำถาม # 5:
ใช่คุณเข้าใจถูกแล้วที่ openConnection เพียงสร้างออบเจ็กต์การเชื่อมต่อใหม่ แต่ไม่ได้สร้าง การเชื่อมต่อถูกสร้างขึ้นเมื่อคุณเรียกใช้ getInputStream หรือ getOutputStream
openConnection
สร้างวัตถุการเชื่อมต่อใหม่ จากURL.openConnection javadocs :
การเชื่อมต่อใหม่จะเปิดขึ้นทุกครั้งโดยเรียกเมธอด openConnection ของตัวจัดการโปรโตคอลสำหรับ URL นี้
การเชื่อมต่อจะถูกสร้างขึ้นเมื่อคุณเรียกใช้ openConnection และ InputStream, OutputStream หรือทั้งสองอย่างจะถูกเรียกเมื่อคุณสร้างอินสแตนซ์
คำถาม # 6 :
ในการวัดค่าโสหุ้ยโดยทั่วไปฉันจะห่อรหัสเวลาที่เรียบง่ายรอบ ๆ บล็อกการเชื่อมต่อทั้งหมดดังนี้:
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) );
ฉันแน่ใจว่ามีวิธีการขั้นสูงเพิ่มเติมในการวัดเวลาขอและค่าใช้จ่าย แต่โดยทั่วไปแล้วก็เพียงพอสำหรับความต้องการของฉัน
สำหรับข้อมูลเกี่ยวกับการปิดการเชื่อมต่อที่คุณไม่ได้ถามโปรดดูใน Java เมื่อการเชื่อมต่อ URL ปิด? .