為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)");
。