1. 程式人生 > >HttpURLConnection與HttpClient學習

HttpURLConnection與HttpClient學習

就是 int main head title tac localhost local net

轉載HttpURLConnection與HttpClient淺析

一、HttpURLConnection的使用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpURLConnectionUtil { private static final Logger logger = LoggerFactory.getLogger(HttpURLConnection.class); /** * get請求 * @param urlStr 請求地址 * @param param 請求參數 */ public static void Get(String urlStr,String param) { try { urlStr = urlStr + "
?"+param; // 1.獲取訪問地址 URL url = new URL(urlStr); // 2.獲取網絡訪問對象 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); /* 3.設置請求參數(過期時間、輸入/輸出流、訪問方式),以流的形式進行連接 */ // 設置是否向HttpURLConnection輸出 connection.setDoOutput(false
); // 設置是否向HttpURLConnection讀入 connection.setDoInput(true); // 設置請求方式 connection.setRequestMethod("GET"); // 設置是否使用緩存 connection.setUseCaches(true); // 設置HttpURLConnection實例是否自動執行HTTP重定向 connection.setInstanceFollowRedirects(true); // 設置超時時間 connection.setConnectTimeout(3000); // 連接 connection.connect(); // 4.得到相應狀態碼的返回值 int responseCode = connection.getResponseCode(); logger.info("Get-responseCode:"+responseCode); // 5.如果返回值正常,數據在網絡中是以流的形式得到服務器返回的數據 String msg = ""; // 正常響應 if(responseCode == 200) { // 從流中讀取數據 BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream()) ); String line = null; // 循環從流中讀取 while ((line = reader.readLine()) != null) { msg += line + "\n"; } reader.close(); } // 6.斷開連接,釋放資源 connection.disconnect(); // 響應數據 System.out.println(msg); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * post請求 * @param urlStr 請求地址 * @param param 請求參數 */ public static void Post(String urlStr, String param) { try { // 1.獲取訪問地址 URL url = new URL(urlStr); // 2.獲取網絡訪問對象 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); /* 3.設置請求參數(過期時間、輸入/輸出流、訪問方式),以流的形式進行連接 */ // 設置請求方式 connection.setRequestMethod("POST"); // 設置超時時間 connection.setConnectTimeout(3000); // 設置是否向HttpURLConnection輸出 connection.setDoOutput(true); // 設置是否向HttpURLConnection讀入 connection.setDoInput(true); // 設置是否使用緩存 connection.setUseCaches(false); // 設置HttpURLConnection實例是否自動執行HTTP重定向 connection.setInstanceFollowRedirects(true); // 設置使用標準編碼格式編碼參數的名-值對 connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); // 連接 connection.connect(); /* 4. 處理輸入輸出 */ // 寫入參數到請求中 OutputStream out = connection.getOutputStream(); out.write(param.getBytes()); out.flush(); out.close(); // 從連接中讀取響應數據 String msg = ""; int responseCode = connection.getResponseCode(); logger.info("Post-reponseCode:"+responseCode); if(responseCode == 200) { BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream()) ); String line = ""; while ((line = reader.readLine()) != null) { msg += line + "\n"; } reader.close(); } connection.disconnect(); System.out.println(msg); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { String urlStr = "http://localhost:8080/aa"; String param = "name=nana"; Get(urlStr,param); Post(urlStr,param); } }

說明:

  1. HttpURLConnection對象不能直接構造,需要通過URL類中的openConnection()方法來獲得。
  2. HttpURLConnection的connect()函數,實際上只是建立了一個與服務器的TCP連接,並沒有實際發送HTTP請求。HTTP請求實際上直到我們獲取服務器響應數據(如調用getInputStream()、getResponseCode()等方法)時才正式發送出去。
  3. 對HttpURLConnection對象的配置都需要在connect()方法執行之前完成。
  4. HttpURLConnection是基於HTTP協議的,其底層通過socket通信實現。如果不設置超時(timeout),在網絡異常的情況下,可能會導致程序僵死而不繼續往下執行。
  5. HTTP正文的內容是通過OutputStream流寫入的, 向流中寫入的數據不會立即發送到網絡,而是存在於內存緩沖區中,待流關閉時,根據寫入的內容生成HTTP正文。
  6. 調用getInputStream()方法時,返回一個輸入流,用於從中讀取服務器對於HTTP請求的返回信息。
  7. 我們可以使用HttpURLConnection.connect()方法手動的發送一個HTTP請求,但是如果要獲取HTTP響應的時候,請求就會自動的發起,比如我們使用HttpURLConnection.getInputStream()方法的時候,所以完全沒有必要調用connect()方法。

二、HttpURLConnection的使用

1.HttpClient簡介:

  在一般情況下,如果只是需要向Web站點的某個簡單頁面提交請求並獲取服務器響應,HttpURLConnection完全可以勝任。但在絕大部分情況下,Web站點的網頁可能沒這麽簡單,這些頁面並不是通過一個簡單的URL就可訪問的,可能需要用戶登錄而且具有相應的權限才可訪問該頁面。在這種情況下,就需要涉及Session、Cookie的處理了,如果打算使用HttpURLConnection來處理這些細節,當然也是可能實現的,只是處理起來難度就大了。
  為了更好地處理向Web站點請求,包括處理Session、Cookie等細節問題,Apache開源組織提供了一個HttpClient項目,看它的名稱就知道,它是一個簡單的HTTP客戶端(並不是瀏覽器),可以用於發送HTTP請求,接收HTTP響應。但不會緩存服務器的響應,不能執行HTML頁面中嵌入的Javascript代碼;也不會對頁面內容進行任何解析、處理。
  簡單來說,HttpClient就是一個增強版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection沒有提供的有些功能,HttpClient也提供了,但它只是關註於如何發送請求、接收響應,以及管理HTTP連接。

2. HttpClient的使用:

  • 創建HttpClient對象。
  • 如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
  • 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HttpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
  • 調用HttpClient對象的execute(HttpUriRequest request)發送請求,執行該方法返回一個HttpResponse。
  • 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。

3. HttpClient的使用例子:

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

public class HttpClientUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    public static void Get(String urlStr,String param) {
        // 1.創建HttpClient對象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 2.創建HttpGet對象
        HttpGet httpGet = new HttpGet(urlStr);
        CloseableHttpResponse response= null;
        try {
            // 3.創建GET請求
            response = httpClient.execute(httpGet);
            System.out.println(response.getStatusLine());
            // 4.獲取響應實體
            HttpEntity entity = response.getEntity();
            // 5.處理響應實體
            if (entity != null) {
                logger.info("長度:" + entity.getContentLength());
                logger.info("內容:" + EntityUtils.toString(entity));
            }
        }  catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 6.釋放資源
            try {
                response.close();
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void Post(String urlStr, String param) {
        // 1.創建HttpClient對象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 2.創建HttpPost對象
        HttpPost post = new HttpPost(urlStr);
        // 3.設置POST請求傳遞參數
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("name","wln"));
        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) {
                logger.info("響應內容:"+EntityUtils.toString(entity));
            }
            response.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 釋放資源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        String urlStr = "http://localhost:8080/bb";
        String param = "";
        Get(urlStr,param);
        Post(urlStr,param);
    }
}

註:使用時要導入下面的jar包

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.1</version>
</dependency>

4.說明

  HttpClient相比傳統JDK自帶的URLConnection,增加了易用性和靈活性,它不僅使客戶端發送HTTP請求變得容易,而且也方便了開發人員測試接口(基於Http協議的),即提高了開發的效率,也方便提高代碼的健壯性。

HttpURLConnection與HttpClient學習