HttpClient常用的一些常識


HttpClient是目前我們通訊組件中最常見的一個Api了吧。至少從我目前接觸到與外部系統通訊的話是這樣的。下面我將我自己常用的一些知識總結一下。

因為本猿也是邊寫邊總結,有啥不對的還望多多指出。

1:利用httpClient發送https請求。

第一次遇到這種情況是開發與微信支付的接口。適用情形https請求,報文格式:字符串(包含json字符串和xml字符串)。

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;
 }

/**
 * 用於進行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請求)

相信有很多人遇到過和我一樣的情形,與外部系統對接時。經常是測試環境使用的是http請求而生產正式環境則是https請求。這時候我是這樣做的。

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();
    }

 //設置超時時間
    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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM