1. 程式人生 > >為GET和POST請求新增請求引數和請求頭

為GET和POST請求新增請求引數和請求頭

  我們平常瀏覽各個網站時,不免有時候就需要填寫一些資訊,比如註冊時,登入時,這些資訊一般都是通過GET請求或者POST(敏感資訊一般使用POST,資料隱藏,相對來說更安全)請求提交到後臺,經過後臺的一系列處理,再返回給前臺結果,前臺進行處理。

GET請求攜帶請求引數和請求頭:

@Test
public void getParams() {

    // 獲取連線客戶端工具
    CloseableHttpClient httpClient = HttpClients.createDefault();

    String entityStr = null;
    CloseableHttpResponse response = null
; try { /* * 由於GET請求的引數都是拼裝在URL地址後方,所以我們要構建一個URL,帶引數 */ URIBuilder uriBuilder = new URIBuilder("http://www.baidu.com"); /** 第一種新增引數的形式 */ /*uriBuilder.addParameter("name", "root"); uriBuilder.addParameter("password", "123456");*/ /** 第二種新增引數的形式 */
List<NameValuePair> list = new LinkedList<>(); BasicNameValuePair param1 = new BasicNameValuePair("name", "root"); BasicNameValuePair param2 = new BasicNameValuePair("password", "123456"); list.add(param1); list.add(param2); uriBuilder.setParameters(list); // 根據帶引數的URI物件構建GET請求物件
HttpGet httpGet = new HttpGet(uriBuilder.build()); /* * 新增請求頭資訊 */ // 瀏覽器表示 httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)"); // 傳輸的型別 httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded"); // 執行請求 response = httpClient.execute(httpGet); // 獲得響應的實體物件 HttpEntity entity = response.getEntity(); // 使用Apache提供的工具類進行轉換成字串 entityStr = EntityUtils.toString(entity, "UTF-8"); } catch (ClientProtocolException e) { System.err.println("Http協議出現問題"); e.printStackTrace(); } catch (ParseException e) { System.err.println("解析錯誤"); e.printStackTrace(); } catch (URISyntaxException e) { System.err.println("URI解析異常"); e.printStackTrace(); } catch (IOException e) { System.err.println("IO異常"); e.printStackTrace(); } finally { // 釋放連線 if (null != response) { try { response.close(); httpClient.close(); } catch (IOException e) { System.err.println("釋放連接出錯"); e.printStackTrace(); } } } // 列印響應內容 System.out.println(entityStr); }

  因為GET請求的引數都是拼裝到URL後面進行傳輸的,所以這地方不能直接新增引數,需要組裝好一個帶引數的URI傳遞到HttpGet的構造方法中,構造一個帶引數的GET請求。構造帶引數的URI使用URIBuilder類。

  上面新增請求引數的方法有兩種,建議後者,後者操作更加靈活。

  • 列印結果:

響應結果

POST請求攜帶請求引數和請求頭:

@Test
public void postParams() {
    // 獲取連線客戶端工具
    CloseableHttpClient httpClient = HttpClients.createDefault();

    String entityStr = null;
    CloseableHttpResponse response = null;

    try {

        // 建立POST請求物件
        HttpPost httpPost = new HttpPost("http://www.baidu.com");

        /*
         * 新增請求引數
         */
        // 建立請求引數
        List<NameValuePair> list = new LinkedList<>();
        BasicNameValuePair param1 = new BasicNameValuePair("name", "root");
        BasicNameValuePair param2 = new BasicNameValuePair("password", "123456");
        list.add(param1);
        list.add(param2);
        // 使用URL實體轉換工具
        UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");
        httpPost.setEntity(entityParam);

        /* 
         * 新增請求頭資訊
         */
        // 瀏覽器表示
        httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
        // 傳輸的型別
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

        // 執行請求
        response = httpClient.execute(httpPost);
        // 獲得響應的實體物件
        HttpEntity entity = response.getEntity();
        // 使用Apache提供的工具類進行轉換成字串
        entityStr = EntityUtils.toString(entity, "UTF-8");

        // System.out.println(Arrays.toString(response.getAllHeaders()));

    } catch (ClientProtocolException e) {
        System.err.println("Http協議出現問題");
        e.printStackTrace();
    } catch (ParseException e) {
        System.err.println("解析錯誤");
        e.printStackTrace();
    } catch (IOException e) {
        System.err.println("IO異常");
        e.printStackTrace();
    } finally {
        // 釋放連線
        if (null != response) {
            try {
                response.close();
                httpClient.close();
            } catch (IOException e) {
                System.err.println("釋放連接出錯");
                e.printStackTrace();
            }
        }
    }

    // 列印響應內容
    System.out.println(entityStr);
}
  • 列印結果:

響應結果
  What?返回的為什麼是個這???很顯然,返回來的程式碼是302重定向

  GET和POST兩種請求方式,GET方式請求無這種情況產生,說明HttpClient對GET進行了處理,會自動處理重定向的連線。而POST並沒有做這種處理,所以要手動處理

  PS:這裡有一個小注意事項,在POST請求引數轉換成請求實體(Entity)時,注意編碼格式問題:UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");
  
  我們該怎麼解決這種問題?首先我們要分析,既然是重定向,那麼響應回來的資訊中,頭資訊(hearder)中肯定會存在重定向需要使用到的的鍵值對(Location:"http://www.xxxx.com"),先獲取所有的頭資訊進行列印檢視。

......前省略

    // 執行請求
    response = httpClient.execute(httpPost);
    // 獲得響應的實體物件
    HttpEntity entity = response.getEntity();
    // 使用Apache提供的工具類進行轉換成字串
    entityStr = EntityUtils.toString(entity, "UTF-8");

    /** 此處獲取所有的響應頭資訊並進行列印 */
    System.out.println(Arrays.toString(response.getAllHeaders()));

} catch (ClientProtocolException e) {
    System.err.println("Http協議出現問題");
    e.printStackTrace();
} catch (ParseException e) {

......後省略
  • 列印結果

響應結果

  這時我們只需要獲取到Location的值,再對其進行再次訪問即可

  其實這裡隱含了一個問題,敲重點...這裡我直接獲取所有的響應資訊的頭資訊並進行列印,其中是存在Location這個key的,這是因為在程式碼中具有以下程式碼所以才會有這個返回資訊。

  • 瀏覽器標識請求頭資訊:
httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");

如果沒有上面的瀏覽器標識的話,有些網站是不會顯示Location地址的。
httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");

  • 列印結果:
    [Server: bfe/1.0.8.18, Date: Tue, 18 Jul 2017 06:28:09 GMT, Content-Type: text/html, Content-Length: 17931, Connection: Keep-Alive, ETag: “54d9748e-460b”]

  可以看到,其中並沒有Location,這時候就需要加上httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");