介面測試“八重天”---HttpClient
HTTP協議在網際網路無處不在,在前面的章節中記錄了‘介面本質即協議’,因此,介面測試首先了解的便是協議,其傳送資料包和接收資料包的過程,其次便是如何在測試中去傳送去解析,不論是通過程式碼還是工具也好,抽空學習一下HttpClient。
HttpClient基本概念
(官方地址:http://hc.apache.org/httpclient-3.x/)
HttpClient 是Apache Jakarta Common 下的子專案,可以用來提供高效的、最新的、功能豐富的支援 HTTP 協議的客戶端程式設計工具包,並且它支援 HTTP 協議最新的版本和建議。(百度百科)
HttpClient
它的一個基本特徵還是有必要去了解的:
- 基於標準的純Java,HTTP版本1.0和1.1的實現
- 在可擴充套件的OO框架中完全實現所有HTTP方法(GET,POST,PUT,DELETE,HEAD,OPTIONS和TRACE)。
- 支援使用HTTPS(HTTP over SSL)協議進行加密。
- 精細的非標準配置和跟蹤。
- 通過HTTP代理進行透明連線。
- 通過HTTP代理通過CONNECT方法進行隧道連線。
- 使用本機Java套接字支援通過SOCKS代理(版本4和5)進行透明連線。
- 使用Basic,Digest和加密NTLM(NT Lan Manager)方法進行身份驗證。
- 用於自定義身份驗證方法的外掛機制。
- 用於上載大檔案的多部分表單POST。
- 可插拔的安全套接字實現,使其更易於使用第三方解決方案
- 連線管理支援在多執行緒應用程式中使用。支援設定最大總連線數以及每個主機的最大連線數。檢測並關閉陳舊連線。
- 用於讀取Set-Cookie的自動Cookie處理:來自伺服器的標頭,並在適當時將其傳送回Cookie:標頭。
- 用於自定義cookie策略的外掛機制。
- 請求輸出流以避免通過直接流式傳輸到伺服器的套接字來緩衝任何內容主體。
- 響應輸入流通過直接從套接字流式傳輸到伺服器來有效地讀取響應主體。
- 使用HTTP / 1.0中的KeepAlive和HTTP / 1.1中的持久連線的持久連線
- 直接訪問伺服器傳送的響應程式碼和標頭。
- 設定連線超時的能力。
- HttpMethods實現命令模式以允許並行請求和連線的有效重用。
- 原始碼可在Apache軟體許可下免費獲得。
百度百科上有其詳細的執行步驟:
1、建立Httpclient例項;
2、建立某種連線方法的例項,在這裡是GetMethod。在 GetMethod 的建構函式中傳入待連線的地址;
3、呼叫第一步中建立好的例項的 execute 方法來執行第二步中建立好的 method 例項;
4、讀 response;
5、釋放連線。無論執行方法是否成功,都必須釋放連線;
6、對得到後的內容進行處理。
官方教程:
1、例項化Httpclient
HttpClient client = new HttpClient();
2、建立方法
HttpMethod method = new GetMethod("http://www.apache.org/");
3、執行方法
// set per default client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
4、讀取response
byte [] responseBody = method.getResponseBody();
5、釋放連線
method.releaseConnection();
6、處理返回資料
System.out.println(new String(responseBody));
最終例項
import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; import java.io.*; public class HttpClientTutorial { private static String url = "http://www.apache.org/"; public static void main(String[] args) { // Create an instance of HttpClient. HttpClient client = new HttpClient(); // Create a method instance. GetMethod method = new GetMethod(url); // Provide custom retry handler is necessary method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); try { // Execute the method. int statusCode = client.executeMethod(method); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + method.getStatusLine()); } // Read the response body. byte[] responseBody = method.getResponseBody(); // Deal with the response. // Use caution: ensure correct character encoding and is not binary data System.out.println(new String(responseBody)); } catch (HttpException e) { System.err.println("Fatal protocol violation: " + e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println("Fatal transport error: " + e.getMessage()); e.printStackTrace(); } finally { // Release the connection. method.releaseConnection(); } } }
該例使用的是Get方法,那麼我們日常中使用的方法最多的無外乎Get和Post方法,那麼就找一下這兩個方法的例子。
例項
該例項取自:https://www.cnblogs.com/sharpest/p/7831350.html。
/** * @author Richered * HttpClientGET */ package com.me.learn; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; public class HttpClientGET { public static void main(String []args) { //建立httpclient物件 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); //建立httpclientget方法物件 HttpGet httpGet = new HttpGet("https://www.baidu.com"); CloseableHttpResponse response = null; try { // 3. 執行GET請求 response = httpClient.execute(httpGet); System.out.println(response.getStatusLine()); // 4. 獲取響應實體 HttpEntity entity = response.getEntity(); // 5. 處理響應實體 if (entity != null) { System.out.println("長度:" + entity.getContentLength()); System.out.println("內容:" + EntityUtils.toString(entity)); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 6. 釋放資源 try { response.close(); httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * @author Richered * HttpClientPOST */ package com.me.learn; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpClientPOST { public static void main(String[] args) { // TODO Auto-generated method stub // 1. 建立HttpClient物件 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); // 2. 建立HttpPost物件 HttpPost post = new HttpPost( "https://www.baidu.com"); // 3. 設定POST請求傳遞引數 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", "test")); params.add(new BasicNameValuePair("password", "12356")); try { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params); post.setEntity(entity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 4. 執行請求並處理響應 try { CloseableHttpResponse response = httpClient.execute(post); HttpEntity entity = response.getEntity(); if (entity != null){ System.out.println("響應內容:"); System.out.println(EntityUtils.toString(entity)); } response.close(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 釋放資源 try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } }