HttpClient是目前咱們通信組件中最多見的一個Api了吧。至少從我目前接觸到與外部系統通信的話是這樣的。下面我將我本身經常使用的一些知識總結一下。json
由於本猿也是邊寫邊總結,有啥不對的還望多多指出。服務器
1:利用httpClient發送https請求。微信
第一次遇到這種狀況是開發與微信支付的接口。適用情形https請求,報文格式:字符串(包含json字符串和xml字符串)。ide
public String doPost(String url,String charset,String reqXmlData){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
//這裏是關鍵,SSLClient繼承了DefaultHttpClient 忽略https校驗過程。SSLClient具體以下。
httpClient = new SSLClient();
logger.info("call weixin pay url:"+url);
httpPost = new HttpPost(url);
logger.info("call weixin pay requestXmlData:"+reqXmlData);
//設置最簡單的字符串請求參數
StringEntity strEntity = new StringEntity(reqXmlData, charset);
httpPost.setEntity(strEntity);
HttpResponse response = httpClient.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if(code == 200){
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}else{
//這裏就不對其餘code處理了
}
logger.info("call weixin pay responseXmlData:"+result);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if (httpClient != null){
httpClient = null;
}
}
return result;
}post
/**
* 用於進行Https請求的HttpClient
*/
public class SSLClient extends DefaultHttpClient{
public SSLClient() throws Exception{
super();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
}
}測試
好了,今天就先更新到這裏了。下班肥家。20151207微信支付
第二點:利用httpclient來模擬表單提交(兼容http請求和https請求)this
相信有不少人遇到過和我同樣的情形,與外部系統對接時。常常是測試環境使用的是http請求而生產正式環境則是https請求。這時候我是這樣作的。url
public static String httpPost(String reqUrl, BaseDto baseDto){
DefaultHttpClient httpclient = new DefaultHttpClient();
String result = "";
try {
if(reqUrl.startsWith("https")){
logger.debug("請求地址爲https請求");
httpclient = new SSLClient();
}spa
//設置超時時間
httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIME_OUT * 1000);
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, TIME_OUT * 1000);
HttpPost httppost = new HttpPost(reqUrl);
logger.debug("調用地址"+reqUrl);
//定義一個用來存儲表單數據的集合
List<BasicNameValuePair> formParams = new ArrayList<BasicNameValuePair>();
formParams.add(new BasicNameValuePair("merchant_id", baseDto.getMerchant_id()));
formParams.add(new BasicNameValuePair("key_enc", baseDto.getKey_enc()));
formParams.add(new BasicNameValuePair("sign", baseDto.getSign()));
formParams.add(new BasicNameValuePair("xml_enc", baseDto.getXml_enc()));
//UrlEncodedFormEntity與StringEntity相比較的話只能接受鍵值對的形式,試用與表單提交
HttpEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");
httppost.setEntity(entity);
HttpResponse response=httpclient.execute(httppost);
int httpCode = response.getStatusLine().getStatusCode();
logger.debug("返回的code:"+httpCode);
switch (httpCode) {
case 200:
HttpEntity resEntity=response.getEntity();
result = EntityUtils.toString(resEntity,"UTF-8");
logger.debug("通信原始結果:"+result);
return result;
case 401:
logger.debug("請求要求進行身份驗證");
case 403:
logger.debug("請求被拒絕,請檢查IP地址是否已經加入對方白名單");
case 404:
logger.debug("未找到,服務器找不到請求的地址");
case 405:
logger.debug("方法不容許,請確認是否爲POST請求方式");
case 500:
logger.debug("查詢請求失敗,內部錯誤");
default:
logger.debug("未知的返回碼:" + httpCode);
}
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException(e,"0006","獲取渠道返回信息失敗了,多是超時了");
}
}
好了,今天就先更新到這裏了,後面繼續來整理利用httpclient來進行爬蟲。httpclient的超時設置等等。20151208