HttpPost 攜帶引數的請求方式
一、HTTP請求
Http的幾種請求方式對應程式包中的HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, and HttpOptions,這些類均實現了HttpUriRequest介面,所以可以作為execute的執行引數使用。
根據HTTP的請格式,我們可以知道有兩種方式可以為request提供引數。
第一種方式:request-line
第二種方式:request-body
因為工作中使用HttpPost請求用到了這兩種請求方式,所以下面就只列出HttpPost的請求,其他請求方式的等下次用到在補上。
二、HttpPost
1、request-line方式
URI uri = null; List<NameValuePair> qparams = new ArrayList<NameValuePair>(); qparams.add(new BasicNameValuePair("region", String.valueOf(departmentId)));//需要對應傳參的name和value qparams.add(new BasicNameValuePair("platNum", carNum));//需要對應傳參的name和value try { uri = URIUtils.createURI("http", "192.168.1.75:23002", -1, "/zyc/get/latest", URLEncodedUtils.format(qparams, "UTF-8"), null); HttpPost httpPost = new HttpPost(uri); System.out.println(httpPost.getURI()); } catch (URISyntaxException e) { e.printStackTrace(); } catch (JsonProcessingException e) { e.printStackTrace(); }
列印結果如下: http://192.168.1.75:23002/zyc/get/latest?region=320211&platNum
2、request-body
PageHelper pageHelper =new PageHelper(pageIndex,pageSize,null); ObjectMapper MAPPER = new ObjectMapper(); stringPage = MAPPER.writeValueAsString(pageHelper);//物件轉String List<NameValuePair> list = new LinkedList<>(); list.add( new BasicNameValuePair("pageHelper",stringPage ));//pageHelper放在body中傳過去 HttpPost httpPost = new HttpPost(uri); // 使用URL實體轉換工具 UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); //使用 UrlEncodedFormEntity 來設定 body,訊息體內容 httpPost.setEntity(entityParam);
3、HttpPost兩種方式結合在一起請求
/**
* 傳送 post請求
*/
public String postParams(PageHelper pageHelper, Long region, String platNum) {
// 獲取連線客戶端工具
CloseableHttpClient httpClient = HttpClients.createDefault();
String entityStr = null;
CloseableHttpResponse response = null;
ObjectMapper MAPPER = new ObjectMapper();
try {
String stringPage = MAPPER.writeValueAsString(pageHelper);
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("region", String.valueOf(region)));
qparams.add(new BasicNameValuePair("platNum", platNum));
URI uri = null;
try {
uri = URIUtils.createURI("http", "192.168.X.X:23002", -1, "/zyc/get/latestdd",
URLEncodedUtils.format(qparams, "UTF-8"), null);
} catch (URISyntaxException e) {
e.printStackTrace();
}
HttpPost httpPost = new HttpPost(uri);
System.out.println(httpPost.getURI());
// 建立請求引數HttpUriRequest
List<NameValuePair> list = new LinkedList<>();
list.add( new BasicNameValuePair("pageHelper",stringPage ));//放在body中
/*JSONObject postData = new JSONObject();
postData.put("pageHelper", stringPage);
httpPost.setEntity(new StringEntity(postData.toString(), HTTP.UTF_8));*/
// 使用URL實體轉換工具
UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");// UrlEncodedFormEntity request-body
httpPost.setEntity(entityParam);
System.out.println("executing request " + httpPost.getURI());
// 瀏覽器表示
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");
} 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);
return entityStr;
}
注:說一下上面用到的BasicNameValuePair方法
三、BasicNameValuePair方法
new BasicNameValuePair(String1,String2)
BasicNameValuePair方法 進行引數傳遞時,只能使用String這種型別進行傳遞,事實上表單提交的get和post只能傳遞String型別,所以如何傳遞非String型別的引數,比如布林型別、整型或者實體類。
其實第一個想到的就是將這些符合要求的型別轉換成String型別就可以了,但是為什麼可以直接轉呢?
因為,httpPost.setEntity(new UrlEncodedFormEntity(params));這段神奇的程式碼
這裡放到http entity裡面的型別都是位元組型別,HTTP協議與FTP,SMTP類似都是通過plain-text ASCII來進行CS資料通訊的(不像TCP使用二進位制,有歷史原因,也更加節約頻寬和方便除錯),實際上並不存在什麼String,Boolean,Integer資料型別,都是通過將byte進行ASCII編碼來實現的,伺服器端反序列化成String型別後,通過springMVC的框架進行解析,注意這裡也需要區分提交方式,框架可能會選取適當的httpMessageConverter進行解析(這個是伺服器關注的事情了)