在setProxy()方法中設置代理IP后可以將url中的域名換成這個代理IP。
http很簡單,但是https這樣會報錯。
問題:如何使用代理發送https請求?
客戶端發送https請求之前會先向這台服務器請求ssl證書,並在客服端對這個證書做一個校驗。
而使用代理IP時,實際上請求打到了這個代理IP上,而客戶端並不知道這件事,他仍然在等待url域名中所對應的ssl證書,而這代理ip對應的服務器實際上並沒有這個證書,導致了https請求失敗。
解決方法:
HttpClient中有一個 類,里面的方法中包含了需要驗證的所有ssl證書類型,而我們只需要重寫這個方法,並把需要驗證的證書設置為空,即命令客戶端不驗證任何ssl證書,就ok了。
關於http請求頭中的host字段:
https://blog.csdn.net/yzpbright/article/details/51052008
代碼:
private JSONObject HttpPing(String dns, String uri, String qlb, String scheme) { String url = scheme + "://" + dns + uri; CloseableHttpClient httpclient = null; if (scheme.equals("http")) { httpclient = getHttpClient(qlb); } else if (scheme.equals("https")) { httpclient = getHttpsClient(qlb); } else{ return null; } HttpGet httpGet = new HttpGet(url); CloseableHttpResponse httpResp = null; try { httpResp = httpclient.execute(httpGet); } catch (IOException e) { e.printStackTrace(); } try { int statusCode = httpResp.getStatusLine().getStatusCode(); if (statusCode == org.apache.http.HttpStatus.SC_OK) { return JSONObject.parseObject(EntityUtils.toString(httpResp.getEntity(), "UTF-8")); } } catch (Exception e) { e.printStackTrace(); } finally { try { httpResp.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } private CloseableHttpClient getHttpClient(String qlb) { HttpHost proxy = new HttpHost(qlb, 80, "http"); //把代理設置到請求配置 RequestConfig defaultRequestConfig = RequestConfig.custom() .setProxy(proxy) .build(); CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build(); return httpclient; } private CloseableHttpClient getHttpsClient(String qlb) {
//這里設置客戶端不檢測服務器ssl證書 try { X509TrustManager x509mgr = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) { } public void checkServerTrusted(X509Certificate[] xcs, String string) { } public X509Certificate[] getAcceptedIssuers() { return null; } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { x509mgr }, null); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpHost proxy = new HttpHost(qlb, 443, "https"); RequestConfig defaultRequestConfig = RequestConfig.custom() .setProxy(proxy) .build(); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(defaultRequestConfig).build(); return httpclient; } catch (Exception e) { e.printStackTrace(); } return null; }