記一次HTTPClient模擬登錄獲取Cookie的開發歷程

記一次HTTPClient模擬登錄獲取Cookie的開發歷程

環境:

​ springboot : 2.7

​ jdk: 1.8

​ httpClient : 4.5.13

設計方案

​ 通過新建一個空的cookie庫創建出一個Http客戶端,然後通過此客戶端調用登錄介面模擬登錄拿到cookie數據,登錄成功 cookie會自動存儲到我們之前新建的空cookie庫中,將此cookie庫保存下來,後續其他介面調用每次都通過這個登錄成功的cookie庫創建出新的http客戶端來發起http訪問。

程式碼實現:

    /**
     * 每個cookie只能綁定一個客戶端,提供這個方法用於給cookie生成http客戶端
     *
     * @param basicCookieStore: cookie
     * @Author: sanghaiquan
     * @Date: 2022/11/9 10:45
     * @return: org.apache.http.impl.client.CloseableHttpClient
     **/
    private static CloseableHttpClient getHttpsClient(BasicCookieStore basicCookieStore) throws KeyManagementException, NoSuchAlgorithmException {
        CloseableHttpClient httpClient = null;
        SSLContext sslContext = SSLContext.getInstance("TLS");
        X509TrustManager x509TrustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sslContext.init(null, new TrustManager[]{x509TrustManager}, null);

        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                sslContext,
                new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"},
                null,
                NoopHostnameVerifier.INSTANCE
        );
        httpClient = HttpClients.custom()
          			// 設置跳過SSL認證
                .setSSLSocketFactory(sslConnectionSocketFactory)
                // 設置客戶端默認的cookie
                .setDefaultCookieStore(basicCookieStore)
                // 每個route默認的最大連接數
                .setMaxConnPerRoute(100)
                // 總的連接池最大連接數
                .setMaxConnTotal(500)
                .build();


        return httpClient;
    }

問題記錄:

​ 獲取到的cookiestore由於內部結構原因,無法被redis正常反序列化,如果需要將cookie持久化存儲,那麼就需要將cookiestore中的cookiesGet獲取出來,並轉換成list然後存儲到reids中,因為cookiestore中cookies的數據類型默認是LIst<cookie介面>,泛型是介面導致無法使用redis反序列化,故需要進行轉換操作。

​ 並且在編寫程式碼過程中,list類型存儲的cookes數據在使用GenericJasksonRedisSerializer在從redis中取出進行反序列化時仍舊會報錯,無法轉換,具體原因待分析,故將序列化改為GenericFastJsonRedisSerializer進行序列化,問題解決。

存疑點:

​ 1.頻繁使用cookie創建新的httpclient是否會影響性能?

​ 2.有沒有使用唯一的一個httpclient每次去新的cookiestore的辦法,類似於Token機制一樣,只需要創建一個默認的httpclient即可,全局通過,無需頻繁創建銷毀httpclient。