一、簡介
HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支持HTTP協議的客戶端編程工具包,並且它支持HTTP協議最新的版本和建議
二、特性
1、基於標准的java語言
2、以可擴展的面向對象的結構實現了GET、POST、PUT等Http的全部方法
3、支持https協議
4、 Request的輸出流可以避免流中內容直接緩沖到socket服務器。
5、Response的輸入流可以有效的從socket服務器直接讀取相應內容。
三、使用方法
1、創建HttpClient對象。(推薦用CloseableHttpClient,HttpClient是歷史遺留版本,官方推薦使用CloseableHttpClient)
**注:兩者的依賴不同
2、創建請求方法的實例,並指定請求uri。如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
3、如果需要發送請求參數,直接在請求地址后拼接參數(√);對於HttpPost對象而言,也可先設置參數隊列,然后調用setEntity(HttpEntity entity)方法來設置請求參數。
4、調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse/CloseableHttpResponse。
5、調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,如果出現亂碼,可以將HttpEntity對象改成StringEntity,可通過該對象獲取服務器的響應內容。
6、釋放連接,無論方法是否執行成功,都應當必須釋放
所需依賴maven
<!--HttpClient--> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <!--CloseableHttpClient--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.10</version> </dependency>
四、案例
以get、post、文件上傳舉例
Post:(有參數)
```java /** * 表單提交(未封裝方法) */ public class Second { // *創建默認的httpClient實例(CloseableHttpClient). static CloseableHttpClient httpclient = HttpClients.createDefault(); public static void main(String[] args){ // *創建HttpPost HttpPost httppost = new HttpPost("http://localhost:8080/warnWeathers/save"); // *創建參數隊列 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("winfo", "紅色降雨預警,請勿隨意外出游玩")); nvps.add(new BasicNameValuePair("wtype", "紅色降雨預警")); nvps.add(new BasicNameValuePair("warea", "香洲,斗門")); nvps.add(new BasicNameValuePair("wdays", "2")); UrlEncodedFormEntity uefEntity; try { // 設置實體類參數編碼格式 uefEntity = new UrlEncodedFormEntity(nvps, "UTF-8"); // *發送請求參數 httppost.setEntity(uefEntity); // 測試:輸出請求地址 // System.out.println("executing request " + httppost.getURI()); // *調用HttpClient對象的execute發送請求方法並返回一個httpClient/CloseableHttpResponse對象 CloseableHttpResponse response = httpclient.execute(httppost); try { // *調用HttpResponse的getEntity()方法可獲取HttpEntity對象 // HttpEntity-->StringEntity 解決亂碼問題 HttpEntity entity = response.getEntity(); // 獲取響應內容以及響應頭 String message = EntityUtils.toString(entity, "UTF-8"); Header[] allHeaders = response.getAllHeaders(); if (message != null) { System.out.println("響應頭:"+allHeaders); System.out.println("Response content: " + message); } // *關閉連接,釋放資源 } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } }
文件上傳:
/** * 上傳文件 */ public void upload() { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/uploads.action"); FileBody filebody = new FileBody(new File("D:\\image\\1.jpg")); StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN); HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("filebody", filebody).addPart("comment", comment).build(); httppost.setEntity(reqEntity); System.out.println("executing request " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); try { System.out.println(response.getStatusLine()); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { System.out.println("Response content length: " + resEntity.getContentLength()); } EntityUtils.consume(resEntity); } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } }
Get:
/** *無參Get請求方法 *帶參的可直接在請求地址后拼接 */ public class First { // *創建默認的httpClient實例(CloseableHttpClient). static CloseableHttpClient httpclient = HttpClients.createDefault(); public static void main(String[] args) throws Exception{ // *創建HttpGet請求 HttpGet httpGet = new HttpGet("http://localhost:8080/warnWeathers/findAll"); // *執行get請求 HttpResponse response = httpclient.execute(httpGet); if (response.getStatusLine().getStatusCode() == 200) { // *調用HttpResponse的getEntity()方法可獲取HttpEntity對象 HttpEntity resEntity = response.getEntity(); String message = EntityUtils.toString(resEntity, "utf-8"); //根據所需自行 System.out.println("狀態碼:"+response.getStatusLine().getStatusCode()); System.out.println("響應狀態:"+response.getStatusLine()); System.out.println("地區:"+response.getLocale()); System.out.println("返回數據類型:"+resEntity.getContentType()); System.out.println("響應內容:"+message); } else { System.out.println("出錯啦,快去找一下原因!狀態碼是:"+response.getStatusLine().getStatusCode()); } } }
附:
關於RequestConfig配置
//創建RequestConfig RequestConfig defaultRequestConfig = RequestConfig.custom() //一、連接超時,指的是連接一個url的連接等待時間 .setConnectTimeout(1000) // 二、讀取數據超時,指的是連接上一個url,獲取response的返回等待時間 .setSocketTimeout(1000) //三、從連接池獲取連接的超時時間 .setConnectionRequestTimeout(5000) .build();
// 這個超時可以設置為客戶端級別,作為所有請求的默認值: CloseableHttpClient httpclient = HttpClients.custom() .setDefaultRequestConfig(defaultRequestConfig) .build(); // httpclient.execute(httppost)可以讓httppost直接享受到httpclient中的默認配置. // Request不會繼承客戶端級別的請求配置,所以在自定義Request的時候,需要將客戶端的默認配置拷貝過去: HttpGet httpget = new HttpGet("http://www.baidu.com/"); RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) .setProxy(new HttpHost("myotherproxy", 8080)) .build(); httpget.setConfig(requestConfig); // httpget可以單獨地使用新copy的requestConfig請求配置,不會對別的request請求產生影響
