日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HttpClient:绕开https证书(三)

發布時間:2024/10/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HttpClient:绕开https证书(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能,但是對于大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient。

當前官網最新版介紹頁是:Apache HttpComponents – HttpClient Overview

使用HttpClient發送請求、接收響應很簡單,一般需要如下幾步即可:

  • 創建CloseableHttpClient對象。
  • 創建請求方法的實例,并指定請求URL。如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
  • 如果需要發送請求參數,可可調用setEntity(HttpEntity entity)方法來設置請求參數(包括body參數)。setParams方法已過時(4.4.1版本)。
  • 調用HttpGet、HttpPost對象的setHeader(String name, String value)方法設置header信息,或者調用setHeaders(Header[] headers)設置一組header信息(addHeader也可以,但是set更好,因為set會去重)。
  • 調用CloseableHttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個CloseableHttpResponse。
  • 調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容;調用CloseableHttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭。
  • 釋放連接。無論執行方法是否成功,都必須釋放連接
  • 使用https就需要重新構建sslContext對象,把證書塞進去(因為可以改變策略的地方叫較多,很多人一開始被搞得暈頭轉向,不如全圍繞sslContext來構建)

    // 構建一個新的證書管理器,重寫本該校驗的方法,空的就行 public class AlltrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];} }

    寫一個https的工具類:

    import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import sun.misc.JavaSecurityAccess;import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Map; import java.util.logging.Logger;public class HttpUtils {private static Logger logger = Logger.getLogger("HttpUtils.class");public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {//關鍵就是這個sslcontextSSLContext context = SSLContext.getInstance("SSLv3");X509TrustManager[] alltrustManager = new X509TrustManager[0];context.init(null,alltrustManager, new SecureRandom() );return context;}public static String doPostRequest(String url, Map<String,String> headers,String requestBody) throws NoSuchAlgorithmException, KeyManagementException {SSLContext sslcontext =createIgnoreVerifySSL();// 設置協議http和https對應的處理socket鏈接工廠的對象Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", new SSLConnectionSocketFactory(sslcontext)).build();PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);connManager.setMaxTotal(200);//最大連接數connManager.setDefaultMaxPerRoute(100);//單個服務并發數HttpClients.custom().setConnectionManager(connManager);//創建自定義的httpclient對象CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();//創建post方式請求對象HttpPost httpPost = new HttpPost(url);//添加headerif (headers!=null){for (Map.Entry<String, String> entry : headers.entrySet()) {httpPost.setHeader(entry.getKey(), entry.getValue());}}//添加bodyByteArrayEntity entity = null;try {entity = new ByteArrayEntity(requestBody.getBytes("UTF-8"));entity.setContentType("application/json");} catch (UnsupportedEncodingException e) {logger.info("向服務器承保接口發起http請求,封裝請求body時出現異常"+e);throw new RuntimeException("向服務器承保接口發起http請求,封裝請求body時出現異常", e);}httpPost.setEntity(entity);//執行post請求HttpResponse response = null;try {response = client.execute(httpPost);} catch (IOException e) {logger.info("提交給服務器的請求,不符合HTTP協議"+ e);throw new RuntimeException("提交給服務器的請求,不符合HTTP協議", e);}logger.info("狀態碼:" + response.getStatusLine());return response.toString();}}

    如果不想重寫接口,也可以單獨構造:

    /** * 繞過驗證 * * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */ public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sc = SSLContext.getInstance("SSLv3"); // 實現一個X509TrustManager接口,用于繞過驗證,不用修改里面的方法 X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[] { trustManager }, null); return sc; }

    然后來驗證一下:

    public final static void main(String[] args) throws Exception {String body = "";//采用繞過驗證的方式處理https請求 SSLContext sslcontext = createIgnoreVerifySSL(); //設置協議http和https對應的處理socket鏈接工廠的對象 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslcontext)) .build(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); HttpClients.custom().setConnectionManager(connManager); //創建自定義的httpclient對象 CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build(); //CloseableHttpClient client = HttpClients.createDefault();try{//創建post方式請求對象 HttpPost httpPost = new HttpPost("https://api.douban.com/v2/book/1220562"); //指定報文頭Content-type、User-AgenthttpPost.setHeader("Content-type", "application/x-www-form-urlencoded"); httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");//執行請求操作,并拿到結果(同步阻塞) CloseableHttpResponse response = client.execute(httpPost); //獲取結果實體 HttpEntity entity = response.getEntity(); if (entity != null) { //按指定編碼轉換結果實體為String類型 body = EntityUtils.toString(entity, "UTF-8"); } EntityUtils.consume(entity); //釋放鏈接 response.close(); System.out.println("body:" + body);}finally{client.close();}}

    如果要使用自己的證書呢?

    sslcontext = SSLContexts.custom().loadTrustMaterial(new File("D://https//ca//cl.jks"),"123456".toCharArray(),new TrustSelfSignedStrategy()).build();具體可參考此文:http://www.javashuo.com/article/p-ooekqaim-e.html

    參考:

    使用HttpClient鏈接池進行https單雙向驗證 - JavaShuo

    使用HttpClient發起請求時將參數放入requestBody中_weixin_33721344的博客-CSDN博客

    輕松把玩HttpClient之配置ssl,采用繞過證書驗證實現https_崔成龍 . 勇往直前-CSDN博客

    HttpClient配置SSL繞過https證書_irokay的專欄-CSDN博客

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的HttpClient:绕开https证书(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。