try { HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity, "UTF-8"); Util.log("API,POST回來的數據是:"); Util.log(result); } catch (ConnectionPoolTimeoutException e) { log.e("http get throw ConnectionPoolTimeoutException(wait time out)"); } catch (ConnectTimeoutException e) { log.e("http get throw ConnectTimeoutException"); } catch (SocketTimeoutException e) { log.e("http get throw SocketTimeoutException"); } catch (Exception e) { log.e("http get throw Exception"); } finally { httpPost.abort(); }
以前每次代碼執行到上述代碼的第二行的時候,會等一段時間而後會捕獲到Exception異常。java
固然捕獲的Exception這個異常太大了咱們不便於分析,咱們查看一下httpClient.execute(HttpUriRequest uri)的方法;apache
發下這個方法會拋出IOException, ClientProtocolException這兩個異常,可是在調用方法的時候並無明確捕獲他們兩個。瀏覽器
因此頗有可能在執行post請求的過程當中,遇到了這兩個問題,果真咱們把代碼完善以後安全
try { httpClient = new SSLClient(); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity, "UTF-8"); Util.log("API,POST回來的數據是:"); Util.log(result); } catch (ConnectionPoolTimeoutException e) { log.e("http get throw ConnectionPoolTimeoutException(wait time out)"); } catch (ConnectTimeoutException e) { log.e("http get throw ConnectTimeoutException"); } catch (SocketTimeoutException e) { log.e("http get throw SocketTimeoutException"); } catch (ClientProtocolException e) { log.e("http get throw ClientProtocolException"); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { log.e("http get throw Exception"); } finally { httpPost.abort(); }
上述,完善完畢代碼後捕捉到了IOException異常,咱們把異常打印出來看到了以下信息。app
經過在網上查詢可知,這是缺乏安全證書時出現的異常,解決方案以下:ide
目前咱們採用第二種方案:因爲請求的URL是HTTPS的,爲了不須要證書,因此用一個類繼承DefaultHttpClient類,忽略校驗過程。post
編寫一個SSLClient類測試
package com.phicomm.smarthome.sharedwifi.util; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; 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 { // TODO Auto-generated method stub } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub 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)); } }
對應的實現類:網站
public HttpResponse sendPostToService(String url, Object pushData) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException { if (!hasInit) { init(); } String result = null; HttpPost httpPost = new HttpPost(url); StringEntity postEntity = new StringEntity(pushData.toString(), ContentType.create("application/x-www-form-urlencoded", "UTF-8")); // 設置一些Http頭信息 httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); httpPost.addHeader("connection", "Keep-Alive"); httpPost.addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 將發送內容填裝 httpPost.setEntity(postEntity); // 設置請求器的配置 httpPost.setConfig(requestConfig); // 打印待發送的數據 Util.log("=====API,POST過去的數據是:"); Util.log("executing request" + httpPost.getRequestLine()); Util.log("請求頭信息===" + httpPost.getAllHeaders().toString()); Util.log("請求狀態行===" + httpPost.getRequestLine()); Util.log("請求配置===" + httpPost.getConfig()); Util.log("請求實體===" + httpPost.getEntity().getContentEncoding() + httpPost.getEntity().getContentType() + httpPost.getEntity().getContent()); HttpResponse response = null; try { // 忽略全部的SSL請求的證書 httpClient = new SSLClient(); response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity, "UTF-8"); // 打印獲得的響應信息 Util.log("API,POST回來的數據是:"); Util.log("=====Entity:" + result); Util.log("=====Headers:" + response.getAllHeaders()); Util.log("=====StatusLine:" + response.getStatusLine()); Util.log("=====Locale:" + response.getLocale()); } catch (ConnectionPoolTimeoutException e) { log.e("http get throw ConnectionPoolTimeoutException(wait time out)"); } catch (ConnectTimeoutException e) { log.e("http get throw ConnectTimeoutException"); } catch (SocketTimeoutException e) { log.e("http get throw SocketTimeoutException"); } catch (ClientProtocolException e) { log.e("http get throw ClientProtocolException"); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { log.e("http get throw Exception"); } finally { httpPost.abort(); } return response; }
在第36行使用自定義的SSLClient來忽略掉驗證要求ui
另外注意在postMan中模擬調用的時候咱們是用的x-www-form-urlencoded格式的數據請求,就是application/x-www-from-urlencoded,會將表單內的數據轉換爲鍵值對。
當action爲get時候,瀏覽器用x-www-form-urlencoded的編碼方式把form數據轉換成一個字串(name1=value1&name2=value2...),而後把這個字串append到url後面,用?分割,加載這個新的url。 當action爲post時候,瀏覽器把form數據封裝到http body中,而後發送到server。
因此咱們須要對傳進來的數據作一下處理:
// 拼接x-www-form-urlencoded格式的請求參數 String www_url = "coverimg=" + pushMsgModel.getCoverimg() + "&mode=" + pushMsgModel.getMode() + "&msgcontent=" + pushMsgModel.getMsgContent() + "&msgtype=" + pushMsgModel.getMsgtype() + "&outline=" + pushMsgModel.getOutline() + "&saveRecord=" + pushMsgModel.getSaveRecord() + "&source=" + pushMsgModel.getSource() + "&ticker=" + pushMsgModel.getTicker() + "×tamp=" + pushMsgModel.getTimestamp() + "&title=" + pushMsgModel.getTitle() + "&uid=" + pushMsgModel.getUid() + "&url=" + pushMsgModel.getUrl(); logger.info("x-www-form-urlencoded格式的請求參數爲:" + www_url);
最後效果以下: