HttpClient เป็นไลบรารีการใช้งานการสื่อสาร HTTP ฝั่งไคลเอ็นต์ เป้าหมายของ HttpClient คือการส่งและรับข้อความ HTTP
ฉันเชื่อว่าฉันไม่จำเป็นต้องพูดเพิ่มเติมเกี่ยวกับความสำคัญของโปรโตคอล Http เมื่อเปรียบเทียบกับ URLConnection ที่มาพร้อมกับ JDK แบบดั้งเดิม HttpClient ได้เพิ่มความสะดวกในการใช้งานและความยืดหยุ่น (เราจะหารือเกี่ยวกับความแตกต่างเฉพาะในอนาคต) ไม่เพียงแต่เป็นวิธีสำหรับลูกค้าในการส่งคำขอ Http เท่านั้น แต่ยังอำนวยความสะดวกให้นักพัฒนาทดสอบอินเทอร์เฟซ (ตามโปรโตคอล HTTP) ซึ่งไม่เพียงปรับปรุงประสิทธิภาพของการพัฒนาเท่านั้น แต่ยังอำนวยความสะดวกในการปรับปรุง ความทนทานของโค้ด ดังนั้นความเชี่ยวชาญใน HttpClient จึงมีความสำคัญและจำเป็นมาก หลังจากเชี่ยวชาญ HttpClient แล้ว ฉันเชื่อว่าความเข้าใจในโปรโตคอล Http จะลึกซึ้งยิ่งขึ้น
1. บทนำ
HttpClient เป็นโปรเจ็กต์ย่อยภายใต้ Apache Jakarta Common ซึ่งใช้เพื่อมอบชุดเครื่องมือการเขียนโปรแกรมไคลเอนต์ที่มีประสิทธิภาพ ทันสมัย และมีฟีเจอร์มากมาย ซึ่งรองรับโปรโตคอล HTTP และรองรับเวอร์ชันล่าสุดและคำแนะนำของโปรโตคอล HTTP HttpClient ถูกนำมาใช้ในหลายโครงการ ตัวอย่างเช่น สองโครงการโอเพ่นซอร์สที่มีชื่อเสียงอื่น ๆ บน Apache Jakarta, Cactus และ HTMLUnit ทั้งคู่ใช้ HttpClient
ที่อยู่การดาวน์โหลด: http://hc.apache.org/downloads.cgi
2. ลักษณะ
1. ขึ้นอยู่กับภาษาจาวามาตรฐานและบริสุทธิ์ ใช้งาน Http1.0 และ Http1.1
2. ใช้วิธีการ Http ทั้งหมด (GET, POST, PUT, DELETE, HEAD, OPTIONS และ TRACE) ด้วยโครงสร้างเชิงวัตถุที่ขยายได้
3. รองรับโปรโตคอล HTTPS
4. สร้างการเชื่อมต่อที่โปร่งใสผ่านพร็อกซี HTTP
5. ใช้วิธี CONNECT เพื่อสร้างการเชื่อมต่อ https แบบทันเนลผ่านพร็อกซี Http
6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos รูปแบบการตรวจสอบสิทธิ์
7. รูปแบบการตรวจสอบสิทธิ์แบบกำหนดเองของปลั๊กอิน
8. โรงงานซ็อกเก็ตแบบพกพาและเชื่อถือได้ช่วยให้ใช้โซลูชันของบุคคลที่สามได้ง่ายขึ้น
9. ตัวจัดการการเชื่อมต่อรองรับแอปพลิเคชันแบบมัลติเธรด รองรับการตั้งค่าจำนวนการเชื่อมต่อสูงสุด รวมถึงการตั้งค่าจำนวนการเชื่อมต่อสูงสุดสำหรับแต่ละโฮสต์ และค้นหาและปิดการเชื่อมต่อที่หมดอายุ
10. จัดการคุกกี้ใน Set-Cookie โดยอัตโนมัติ
11. นโยบายคุกกี้แบบกำหนดเองของปลั๊กอิน
12. สตรีมเอาต์พุตของคำขอสามารถหลีกเลี่ยงการบัฟเฟอร์เนื้อหาในสตรีมโดยตรงไปยังเซิร์ฟเวอร์ซ็อกเก็ต
13. สตรีมอินพุตของการตอบสนองสามารถอ่านเนื้อหาที่เกี่ยวข้องได้โดยตรงจากเซิร์ฟเวอร์ซ็อกเก็ต
14. ใช้ KeepAlive เพื่อรักษาการเชื่อมต่อแบบถาวรใน http1.0 และ http1.1
15. รับโค้ดตอบกลับและส่วนหัวที่ส่งมาจากเซิร์ฟเวอร์โดยตรง
16. ความสามารถในการตั้งค่าการหมดเวลาการเชื่อมต่อ
17. การสนับสนุนการทดลองสำหรับการแคชการตอบสนอง http1.1
18. ซอร์สโค้ดสามารถใช้ได้ฟรีภายใต้ Apache License
3. วิธีการใช้งาน
การใช้ HttpClient เพื่อส่งคำขอและรับการตอบกลับนั้นง่ายมาก โดยทั่วไปแล้ว จำเป็นต้องมีขั้นตอนต่อไปนี้
1. สร้างวัตถุ HttpClient
2. สร้างอินสแตนซ์ของวิธีการร้องขอและระบุ URL คำขอ หากคุณต้องการส่งคำขอ GET ให้สร้างวัตถุ HttpGet หากคุณต้องการส่งคำขอ POST ให้สร้างวัตถุ HttpPost
3. หากคุณต้องการส่งพารามิเตอร์คำขอ คุณสามารถเรียกใช้เมธอด setParams (HetpParams params) ทั่วไปสำหรับ HttpGet และ HttpPost เพื่อเพิ่มพารามิเตอร์คำขอได้ สำหรับวัตถุ HttpPost คุณยังสามารถเรียกใช้เมธอด setEntity (HttpEntity) เพื่อตั้งค่าคำขอได้ พารามิเตอร์
4. เรียกดำเนินการ (คำขอ HttpUriRequest) ของวัตถุ HttpClient เพื่อส่งคำขอ วิธีการนี้จะส่งคืน HttpResponse
5. เรียก getAllHeaders() ของ HttpResponse, getHeaders(String name) และวิธีการอื่นๆ เพื่อรับส่วนหัวการตอบกลับของเซิร์ฟเวอร์ เรียกเมธอด getEntity() ของ HttpResponse เพื่อรับวัตถุ HttpEntity ซึ่งล้อมเนื้อหาการตอบสนองของเซิร์ฟเวอร์ โปรแกรมสามารถรับเนื้อหาการตอบสนองของเซิร์ฟเวอร์ผ่านวัตถุนี้
6. ปล่อยการเชื่อมต่อ ไม่ว่าวิธีดำเนินการจะสำเร็จหรือไม่ก็ตาม การเชื่อมต่อจะต้องถูกปล่อย
4. ตัวอย่าง
แพ็คเกจ com.test; นำเข้า java.io.FileInputStream; นำเข้า java.io.IOException; นำเข้า java.security.KeyStore; security.KeyStoreException; นำเข้า java.security.NoSuchAlgorithmException; java.security.cert.CertificateException; นำเข้า java.util.ArrayList; นำเข้า java.net.ssl.SSLContext; นำเข้า org.apache.http.HttpEntity; org.apache.http.ParseException; นำเข้า org.apache.http.client.ClientProtocolException; org.apache.http.client.entity.UrlEncodedFormEntity; นำเข้า org.apache.http.client.methods.CloseableHttpResponse; นำเข้า org.apache.http.client.methods.HttpGet; นำเข้า org.apache.http.client.methods.HttpPost ;นำเข้า org.apache.http.conn.ssl.SSLConnectionSocketFactory; นำเข้า org.apache.http.conn.ssl.SSLContexts; นำเข้า org.apache.http.conn.ssl.TrustSignedStrategy; org.apache.http.entity.mime.MultipartEntityBuilder; นำเข้า org.apache.http.entity.mime.content.FileBody; นำเข้า org.apache.http.entity.mime.content.StringBody; นำเข้า org.apache.http.impl.client.CloseableHttpClient; .client.HttpClients; นำเข้า org.apache.http.message.BasicNameValuePair; org.apache.http.util.EntityUtils; import org.junit.Test; คลาสสาธารณะ HttpClientTest { @Test public void jUnitTest() { get(); } /** * HttpClient เชื่อมต่อกับ SSL */ public void ssl() { CloseableHttpClient httpclient = null; ลอง { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream instream = new FileInputStream(ไฟล์ใหม่("d://tomcat.keystore")); ลอง { // โหลด keyStore d://tomcat.keystore trustStore.load(instream , "123456".toCharArray()); } catch (CertificateException e) { e.printStackTrace(); } ในที่สุด { ลอง { instream.close(); } catch (ยกเว้นข้อยกเว้น) { } } // เชื่อถือ CA ของคุณเองและใบรับรองที่ลงนามเองทั้งหมด SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build() ; // อนุญาตให้ใช้โปรโตคอล TLSv1 เท่านั้น SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); // สร้างคำขอ http (โหมดรับ) HttpGet httpget = ใหม่ HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action"); System.out.println("กำลังดำเนินการคำขอ" + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); { เอนทิตี HttpEntity = response.getEntity(); System.out.println("--------------------------------- -------"); System.out.println(response.getStatusLine()); if (เอนทิตี != null) { System.out.println("ความยาวเนื้อหาการตอบสนอง: " + เอนทิตี.getContentLength()); System.out.println(EntityUtils.toString (เอนทิตี)); EntityUtils.consume(เอนทิตี); } } ในที่สุด { response.close(); (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } จับ (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } ในที่สุด { ถ้า (httpclient != null) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace() } } /** * ส่งแบบฟอร์มในโหมดโพสต์ (จำลองคำขอเข้าสู่ระบบของผู้ใช้) */ public void postForm() { // สร้างอินสแตนซ์ httpClient เริ่มต้น httpclient = HttpClients.createDefault(); // สร้าง httppost HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action"); // สร้างรายการคิวพารามิเตอร์<namevaluepair> formparams = new ArrayList<namevaluepair>(); , "ผู้ดูแลระบบ")); formparams.add(new BasicNameValuePair("password", "123456")); UrlEncodedFormEntity uefEntity; ลอง { uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httppost.setEntity(uefEntity); System.out.println("กำลังดำเนินการคำขอ" + httppost.getURI()); (httppost); ลอง { เอนทิตี HttpEntity = response.getEntity(); if (เอนทิตี != null) { System.out.println("-------------------------- ------------"); System.out.println("เนื้อหาตอบกลับ: " + EntityUtils.toString(เอนทิตี, "UTF-8")); System.out.println("-- ------------------------------------"); } } ในที่สุด { response.close(); } } จับ (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } ในที่สุด { // ปิดการเชื่อมต่อและปล่อยทรัพยากร ลอง { httpclient .close(); } catch (IOException e) { e.printStackTrace(); } } /** ส่งคำขอโพสต์เพื่อเข้าถึงแอปพลิเคชันในเครื่องและส่งกลับผลลัพธ์ที่แตกต่างกันตามพารามิเตอร์ที่แตกต่างกันที่ส่งผ่าน */ public void post() { // สร้างอินสแตนซ์ httpClient เริ่มต้น = ใหม่ HttpPost(" http://localhost:8080/myDemo/Ajax/serivceJ.action"); // สร้างรายการคิวพารามิเตอร์ <namevaluepair> formparams = new ArrayList<namevaluepair>(); formparams.add(new BasicNameValuePair("type", "house")); UrlEncodedFormEntity uefEntity; "); httppost.setEntity(uefEntity); System.out.println("กำลังดำเนินการคำขอ " + httppost.getURI()); CloseableHttpResponse response = httpclient.execute(httppost); ลอง { HttpEntityentity = response.getEntity()); .println("----------------------------------------------"); .out.println ("เนื้อหาตอบกลับ: " + EntityUtils.toString(เอนทิตี "UTF-8")); System.out.println("--------------------------------- ---------"); } } ในที่สุด { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } จับ (IOException จ) { e.printStackTrace(); } ในที่สุด { // ปิดการเชื่อมต่อและปล่อยทรัพยากรลอง { httpclient.close(); } catch (IOException e) { e.printStackTrace(); / public void get() { CloseableHttpClient httpclient = HttpClients.createDefault(); ลอง { // Create httpget httpget = new HttpGet("http://www.baidu.com/"); System.out.println("กำลังดำเนินการคำขอ " + httpget.getURI()); // ดำเนินการรับคำขอ CloseableHttpResponse = httpclient.execute(httpget); ลอง { // รับเอนทิตีการตอบสนอง HttpEntity เอนทิตี = response.getEntity(); System.out.println("-------------------------- ----------"); // พิมพ์สถานะการตอบกลับ System.out.println(response.getStatusLine()); if (entity != null) { // พิมพ์ความยาวเนื้อหาการตอบกลับ System.out.println("ความยาวเนื้อหาการตอบกลับ: " + เอนทิตี.getContentLength()); //พิมพ์เนื้อหาการตอบกลับ System.out.println("เนื้อหาการตอบกลับ: " + EntityUtils.toString(entity)); System.out.println("--------------------------------------------"); } ในที่สุด { การตอบสนอง .close(); } catch (ClientProtocolException e) { e.printStackTrace(); } ในที่สุด { // ปิดการเชื่อมต่อและปล่อยทรัพยากรลอง { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } /** * อัพโหลดไฟล์*/ public void upload() { CloseableHttpClient httpclient = HttpClients.createDefault(); ลอง { HttpPost httppost = new HttpPost("http://localhost: 8080/myDemo/Ajax/serivceFile.action"); FileBody bin = FileBody ใหม่ (ใหม่ ไฟล์ ("F://image//sendpix0.jpg")); StringBody comment = new StringBody("ไฟล์ไบนารี่บางชนิด", ContentType.TEXT_PLAIN); ", bin).addPart("ความคิดเห็น", ความคิดเห็น).build(); httppost.setEntity(reqEntity); System.out.println("กำลังดำเนินการคำขอ " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); ลอง { System.out.println("------------- ---------------------------------"); System.out.println(response.getStatusLine()); HttpEntity resEntity = การตอบสนอง getEntity( ); ถ้า (resEntity != null) { System.out.println("ความยาวเนื้อหาตอบกลับ: " + resEntity.getContentLength()); } EntityUtils.consume(resEntity); } ในที่สุด { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } ในที่สุด { ลอง { httpclient.close(); } จับ (IOException e) { e.printStackTrace(); } } } }</namevaluepair></namevaluepair></namevaluepair></namevaluepair>
ตัวอย่างนี้ใช้ HttpClient4.3 เวอร์ชันล่าสุด เวอร์ชันนี้ค่อนข้างแตกต่างจากรูปแบบการเขียนโค้ดก่อนหน้า ดังนั้นโปรดให้ความสนใจให้มากขึ้น
เอาล่ะ ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าคุณจะชอบมัน