HttpClient 功能介紹 和 測試DEMO

      一,使用HttpClient發送請求、接收響應在項目中是經常使用的,使用也很簡單,常見的有如下幾步:

1. 創建對象:HttpClient對象。
2. 創建請求方法的實例,並指定請求URL。如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
3. 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HetpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
4. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。
5. 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。
6. 釋放連接。無論執行方法是否成功,都必須釋放連接。

      二, 使用HttpClient遇到的問題。

 1)字符編碼
       某目標頁的編碼可能出現在兩個地方,第一個地方是服務器返回的http頭中,另外一個地方是得到的html/xml頁面中。

在http頭的Content-Type字段可能會包含字符編碼信息。例如可能返回的頭會包含這樣子的信息:Content-Type: text/html; charset=UTF-8。這個頭信息表明該頁的編碼是UTF-8,但是服務器返回的頭信息未必與內容能匹配上。比如對於一些雙字節語言國家,可能服務器返回的編碼類型是UTF-8,但真正的內容卻不是UTF-8編碼的,因此需要在另外的地方去得到頁面的編碼信息;但是如果服務器返回的編碼不是UTF-8,而是具體的一些編碼,比如gb2312等,那服務器返回的可能是正確的編碼信息。通過method對象的getResponseCharSet()方法就可以得到http頭中的編碼信息。

         對於象xml或者html這樣的文件,允許作者在頁面中直接指定編碼類型。比如在html中會有`<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>`這樣的標籤;或者在xml中會有`<?xml version="1.0" encoding="gb2312"?>`這樣的標籤,在這些情況下,可能與http頭中返回的編碼信息衝突,需要用戶自己判斷到底那種編碼類型應該是真正的編碼。

 2)自動轉向
        根據RFC2616中對自動轉向的定義,主要有兩種:301和302。301表示永久的移走(Moved
Permanently),當返回的是301,則表示請求的資源已經被移到一個固定的新地方,任何向該地址發起請求都會被轉到新的地址上。302表示暫時的轉向,比如在服務器端的servlet程序調用了sendRedirect方法,則在客戶端就會得到一個302的代碼,這時服務器返回的頭信息中location的值就是sendRedirect轉向的目標地址。

         HttpClient支持自動轉向處理,但是像 POST 和 PUT 方式這種要求接受後繼服務的請求方式,暫時不支持自動轉向,因此如果遇到 POST 方式提交後返回的是 301或者302 的話需要自己處理。

        另外除了在頭中包含的信息可能使頁面發生重定向外,在頁面中也有可能會發生頁面的重定向。引起頁面自動轉發的標籤是:`<meta http-equiv="refresh" content="5; url=....">`。如果你想在程序中也處理這種情況的話得自己分析頁面來實現轉向。需要注意的是,在上面那個標籤中 url 的值也可以是一個相對地址,如果是這樣的話,需要對它做一些處理後纔可以轉發。

  3)Demo 如下:

Demo1- 無參數的 get請求發送。

/**
 * 處理get請求.
 * @param url  請求路徑
 * @return  json
 */
public String getTest(String url){
    //實例化httpclient
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //實例化get方法
    HttpGet httpget = new HttpGet(url);
    //請求結果
    CloseableHttpResponse response = null;
    String content ="";
    try {
        //執行get方法
        response = httpclient.execute(httpget);
        if(response.getStatusLine().getStatusCode() == 200){
            content = EntityUtils.toString(response.getEntity(),"utf-8");
            log.debug("content: {}", content);
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return content;
}

Demo2- 無參數的 get 請求發送。

/**
 * 發送Get 請求
 *
 * @param url 請求URL
 * @return  json
 */
public static String sendGet(String url) {
    //1.獲得一個httpclient對象
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //2.生成一個get請求
    HttpGet httpget = new HttpGet(url);
    CloseableHttpResponse response = null;
    try {
        //3.執行get請求並返回結果
        response = httpclient.execute(httpget);
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    String result = null;
    try {
        //4.處理結果,這裏將結果返回爲字符串
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            result = EntityUtils.toString(entity);
            log.debug("result ---------- {}", result);
        }
    } catch (ParseException | IOException e) {
        e.printStackTrace();
    } finally {
        try {
            response.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return result;
}

Demo3- 有參數的 post 請求發送。

/**
 * 處理有參數的 post請求.測試1
 * @param url  請求路徑
 * @param params  參數
 * @return  json
 */
public String postTest(String url, Map<String, String> params){
    //實例化httpClient
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //實例化post方法
    HttpPost httpPost = new HttpPost(url);
    //處理參數
    List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    Set<String> keySet = params.keySet();
    for(String key : keySet) {
        nvps.add(new BasicNameValuePair(key, params.get(key)));
    }
    //結果
    CloseableHttpResponse response = null;
    String content="";
    try {
        //提交的參數
        UrlEncodedFormEntity uefEntity  = new UrlEncodedFormEntity(nvps, "UTF-8");
        //將參數給post方法
        httpPost.setEntity(uefEntity);
        //執行post方法
        response = httpclient.execute(httpPost);
        if(response.getStatusLine().getStatusCode() == 200){
            content = EntityUtils.toString(response.getEntity(),"utf-8");
            log.debug("content ---------- {}", content);
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return content;
}
/**
 * 有參數的 post 測試2
 * 
 * @param url
 * @param map
 * @return
 */
public static String sendPost(String url, Map<String, String> map) {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    List<NameValuePair> formparams = new ArrayList<NameValuePair>();
    for (Map.Entry<String, String> entry : map.entrySet()) {
        //給參數賦值
        formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
    }
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
    HttpPost httppost = new HttpPost(url);
    httppost.setEntity(entity);
    CloseableHttpResponse response = null;
    try {
        response = httpclient.execute(httppost);
    } catch (IOException e) {
        e.printStackTrace();
    }
    HttpEntity entity1 = response.getEntity();
    String result = null;
    try {
        result = EntityUtils.toString(entity1);
    } catch (ParseException | IOException e) {
        e.printStackTrace();
    }
    return result;
}

 

Demo4- 無 參數的 post 請求發送。

/**
 * 發送HttpPost的方法和發送HttpGet很類似,只是將請求類型給位HttpPost即可。
 * 發送 不帶參數的 HttpPost請求
 * @param url
 * @return
 */
public static String sendPostNoParams(String url) {
    //1.獲得一個httpclient對象
    CloseableHttpClient httpclient = HttpClients.createDefault();
    //2.生成一個post請求
    HttpPost httppost = new HttpPost(url);
    CloseableHttpResponse response = null;
    try {
        //3.執行get請求並返回結果
        response = httpclient.execute(httppost);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //4.處理結果,這裏將結果返回爲字符串
    HttpEntity entity = response.getEntity();
    String result = null;
    try {
        result = EntityUtils.toString(entity);
        log.debug("result: {}", result);
    } catch (ParseException | IOException e) {
        e.printStackTrace();
    }
    return result;
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章