4.1 เมธอด send() BodyHandlers
คุณได้เรียนรู้วิธีสร้างคำขอ http แล้วดังนั้นคุณจึงสามารถไปยังสิ่งที่สำคัญที่สุด นั่นคือการส่งคำขอนี้ ในกรณีที่ง่ายที่สุด ทำได้ง่าย:
HttpRequest request = HttpRequest.newBuilder(new URI("https://codegym.cc")).build();
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode() );
System.out.println(response.body() );
และBodyHandlers
สิ่งเหล่านี้คืออะไร? คุณคิดอย่างไร? คุณส่งคำขอ ซึ่งหมายความว่าคุณควรได้รับคำตอบhttp response
- และการตอบสนองนี้สามารถมีresponse body
: สตริง, ไฟล์, อาร์เรย์ของไบต์, InputStream
ใช่ใช่ถูกต้อง เช่นเดียวกับเมื่อสร้างคำขอ คุณต้องระบุประเภทresponse body
ของการตอบกลับ สามารถมีทั้งหมด 8 ชิ้น:
BodyHandlers.ofByteArray
BodyHandlers.ofString
BodyHandlers.ofFile
BodyHandlers.discarding
BodyHandlers.replacing
BodyHandlers.ofLines
BodyHandlers.fromLineSubscriber
ขึ้นอยู่กับประเภทที่BodyHandlers
คุณส่งไปยังเมธอดsend()
มันจะส่งคืนประเภทผลลัพธ์ดังกล่าว ตัวอย่าง:
// response body is ignored
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
// response body is a string
HttpResponse<String>response = client.send(request, BodyHandlers.ofString());
// response body is a file
HttpResponse<Path> response = client.send(request, BodyHandlers.ofFile(Paths.get("readme.txt")));
// response body is an InputStream
HttpResponse<InputStream> response = client.send(request, BodyHandlers.ofInputStream());
หากควรส่งไฟล์ถึงคุณเป็นการตอบกลับBodyHandlers.ofFile()
คุณต้องส่งชื่อไฟล์ในเครื่องไปยังเมธอด ซึ่ง HttpClient จะบันทึกไฟล์นั้น
4.2 วิธี followRedirects()
301
นอกจากนี้ เมื่อส่งคำขอ คุณสามารถระบุได้ว่า HttpClient ควรทำอย่างไรหากเซิร์ฟเวอร์ส่ง หรือ302
(เปลี่ยนเส้นทางชั่วคราวหรือถาวร) ตอบกลับ ลองนึกภาพว่าเซิร์ฟเวอร์ได้ส่งรหัส302
และคุณจำเป็นต้อง: ติดตามสถานการณ์นี้ รับ URL ใหม่จากการตอบกลับ และส่งคำขอไปยังที่อยู่ใหม่
ฉันไม่ต้องการทำเช่นนี้มากนัก โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าสถานการณ์นี้เป็นเรื่องปกติและเป็นระบบอัตโนมัติมานานแล้วในไคลเอนต์ http ทั้งหมด นอกจากนี้ ใน HttpClient นี้ คุณเพียงแค่ระบุโหมดการเปลี่ยนเส้นทางที่คุณเลือกเมื่อส่งคำขอ
HttpResponse response = HttpClient.newBuilder()
.followRedirects( HttpClient.Redirect.ALWAYS )
.build()
.send(request, BodyHandlers.ofString());
มีเพียง 3 ตัวเลือกสำหรับการเปลี่ยนเส้นทาง:
- เสมอ - เสมอ;
- ไม่เคย - ไม่เคย;
- ปกติ - เสมอ ยกเว้น HTTPS -> HTTP
อย่างที่คุณเห็น มีตัวเลือกไม่มากนัก แต่การมีความสามารถในการปรับแต่งย่อมดีกว่าการไม่มี
4.4 เมธอด proxy()
มีตัวเลือกที่มีประโยชน์มากกว่าสองสามตัวเลือก แต่ไม่ได้ใช้บ่อยนัก คุณไม่จำเป็นต้องใช้มันจนกว่าคุณต้องการ :)
อันแรกคือพร็อกซี ในชีวิตปกติคุณไม่พบสิ่งเหล่านี้บ่อยนัก แต่องค์กรขนาดใหญ่หลายแห่งมีระบบรักษาความปลอดภัยการรับส่งข้อมูลทางอินเทอร์เน็ตที่ซับซ้อนอยู่ภายใน และด้วยเหตุนี้จึงมีการตั้งค่าพร็อกซีที่หลากหลาย
แน่นอนว่าซอฟต์แวร์ของคุณซึ่งจะทำงานที่ไหนสักแห่งในลำไส้ของ บริษัท ดังกล่าวสักวันหนึ่งจะต้องพบกับความจริงที่ว่าจะต้องใช้พรอกซี ดังนั้นจึงเป็นการดีที่มีตัวเลือกดังกล่าวอยู่ที่นี่ด้วย
การตั้งค่าพร็อกซีนั้นง่ายมาก ตัวอย่าง:
HttpResponse<String> response = HttpClient.newBuilder()
.proxy( ProxySelector.getDefault())
.build()
.send(request, BodyHandlers.ofString());
เลือกพร็อกซีเริ่มต้นที่นี่ แต่คุณอาจต้องการตั้งค่าของคุณเอง:
HttpResponse response = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
.build()
.send(request, BodyHandlers.ofString());
วิธีการทำงานกับพร็อกซีเราจะไม่พิจารณาเนื่องจากไม่รวมอยู่ในขอบเขตของหลักสูตรนี้
4.5 ตัวตรวจสอบความถูกต้อง ()
และอีกหนึ่งจุดสำคัญ โปรโตคอล HTTP รองรับการตรวจสอบสิทธิ์ ในระดับโปรโตคอล
ตอนนี้วิธีนี้แทบจะไม่ได้ใช้ แต่เมื่อประมาณ 20 ปีที่แล้วเป็นเรื่องปกติ คำขอ Http มีลักษณะดังนี้:
http://username@example.com/
หรือแม้แต่เช่นนี้:
http://username:password@example.com/
นี่ไม่ใช่จดหมาย นี่คือลิงค์ และใช่ คุณไม่คิดอย่างนั้น สามารถระบุการเข้าสู่ระบบและแม้แต่รหัสผ่านได้โดยตรงในคำขอ http ใช่ ตอนนี้คุณทำได้แล้ว นั่นเป็นเหตุผลที่ฉันเขียนว่าตอนนี้ไม่มีใครทำสิ่งนี้ แต่มีความเป็นไปได้ดังกล่าว
Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
"username",
"password".toCharArray());
}
};
HttpResponse<String> response = HttpClient.newBuilder()
.authenticator(auth).build()
.send(request, BodyHandlers.ofString());
สิ่งนี้น่าสนใจ! คุณรู้หรือไม่ว่าทำไมแทนที่จะ“password"
เป็นรหัสที่บอกว่า"password".toCharArray()
?
เนื่องจากพารามิเตอร์ที่สองของตัวสร้างPasswordAuthentication
ไม่ใช่String
แต่CharArray
และทำไมพารามิเตอร์ที่สองถึงไม่ใช่String
ฮะCharArray
?
เนื่องจากไม่อนุญาตให้เก็บรหัสผ่านทั้งหมดเป็นสตริงทั้งหมดเพื่อความปลอดภัย แม้แต่ในแอปพลิเคชันของคุณเอง นั่นคือ แอปพลิเคชันของคุณในหน่วยความจำไม่ควรจัดเก็บรหัสผ่านเป็นสตริง ดังนั้นหากมีคนสร้างหน่วยความจำชื้นรหัสผ่านจะไม่สามารถดึงออกมาได้ ...
แต่ในขณะเดียวกัน รหัสผ่านสามารถส่งผ่านโปรโตคอล HTTP ที่ไม่ปลอดภัยไปได้ทั่วโลก :) :) :)
ดี. โลกไม่สมบูรณ์แบบ
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ที่ลิงค์ด้านล่าง: