springboot整合HttpAsyncClient簡單實用

1宾符、pom添加內容

<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpasyncclient</artifactId>
            <version>4.1</version>
        </dependency>

2、創(chuàng)建httpUtil


public class HttpUtil {

    private static int socketTimeout = 1000;// 設置等待數(shù)據(jù)超時時間5秒鐘 根據(jù)業(yè)務調整

    private static int connectTimeout = 2000;// 連接超時

    private static int poolSize = 100;// 連接池最大連接數(shù)

    private static int maxPerRoute = 10;// 每個主機的并發(fā)最多10


    /**
     * 創(chuàng)建非異步的可關閉的且跳過https 驗證的 httpClient
     * @return
     */
    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    /**
     * 創(chuàng)建異步的可關閉的跳過https驗證的 httpClient對象
     * @param connManager  連接管理器  可以調用本類的getConnManager 生成
     * @return
     */
    public static CloseableHttpAsyncClient getClient(PoolingNHttpClientConnectionManager connManager) {
        if (null == connManager) {
            return null;
        }
        // 設置連接參數(shù)
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HttpUtil.socketTimeout).setConnectTimeout(HttpUtil.connectTimeout).build();
        // 創(chuàng)建自定義的httpclient對象
        CloseableHttpAsyncClient client = HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connManager).disableCookieManagement().build();
        return client;
    }

    /**
     * 創(chuàng)建異步的可關閉的跳過https驗證的 httpClient對象(綁定本地網(wǎng)卡)
     * @param connManager
     * @param localAddress
     * @return
     * @throws
     */
    public static CloseableHttpAsyncClient getClient(PoolingNHttpClientConnectionManager connManager, String localAddress) throws UnknownHostException {
        if (null == connManager || null == localAddress) {
            return null;
        }
        String[] ipStrArr = localAddress.split("\\.");
        if(ipStrArr.length != 4){
            return null;
        }
        byte[] ip = new byte[]{ (byte)(Integer.parseInt(ipStrArr[0])), (byte) (Integer.parseInt(ipStrArr[1])), (byte) (Integer.parseInt(ipStrArr[2])), (byte) (Integer.parseInt(ipStrArr[3])) };

        // 設置連接參數(shù)
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HttpUtil.socketTimeout).setConnectTimeout(HttpUtil.connectTimeout).setLocalAddress(InetAddress.getByAddress(ip)).build();
        // 創(chuàng)建自定義的httpclient對象
        CloseableHttpAsyncClient client = HttpAsyncClients.custom().setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connManager).disableCookieManagement().build();
        return client;
    }

    /**
     * 初始化 連接管理器
     * @return
     */
    public static PoolingNHttpClientConnectionManager getConnManager() {

        try {
            // 繞過證書驗證灭翔,處理https請求
            SSLContext sslcontext = createIgnoreVerifySSL();

            // 設置協(xié)議http和https對應的處理socket鏈接工廠的對象
            Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder
                    .<SchemeIOSessionStrategy> create().register("http", NoopIOSessionStrategy.INSTANCE)
                    .register("https", new SSLIOSessionStrategy(sslcontext, new AllowAllHostnameVerifier())).build();
            // 配置io線程
            IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setConnectTimeout(HttpUtil.socketTimeout).setSoTimeout(HttpUtil.connectTimeout)
                    .setRcvBufSize(8192).setSndBufSize(8192).build();

            // 設置連接池大小
            ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);

            PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor, null,
                    sessionStrategyRegistry, null);
            connManager.setDefaultMaxPerRoute(maxPerRoute);
            connManager.setMaxTotal(poolSize);
            return connManager;
        } catch (IOReactorException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 繞過驗證
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext createIgnoreVerifySSL() {
        SSLContext sc = null;
        try {
            sc = SSLContext.getInstance("TLS");
            // 實現(xiàn)一個X509TrustManager接口魏烫,用于繞過驗證,不用修改里面的方法
            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sc.init(null, new TrustManager[] { trustManager }, null);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return sc;

    }

    /**
     * 從 request請求對象 中獲取ip地址
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        if(request==null){
            return null;
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

3肝箱、創(chuàng)建一個提供外部獲取httpClient接口

/**
 * AsynHttpClient工廠類
 */
@Component
public class AsynHttpClientFactory {

    private static Logger logger = LoggerFactory.getLogger(AsynHttpClientFactory.class);


    private static CloseableHttpAsyncClient httpclient;
    private PoolingNHttpClientConnectionManager connManager;
    public AsynHttpClientFactory() {
        connManager = HttpUtil.getConnManager();
        httpclient = HttpUtil.getClient(connManager);
        httpclient.start();
        logger.info("異步httpClient啟動完成");
    }

    public static CloseableHttpAsyncClient getCloseableHttpAsyncClient(){
        return httpclient;
    }

}

4哄褒、測試方法

單個url發(fā)送

 @Test
    public void run(){
        CloseableHttpAsyncClient httpClient =AsynHttpClientFactory.getCloseableHttpAsyncClient();
        long startTime = System.currentTimeMillis();
            final HttpGet request = new HttpGet("http://www.apache.org");
            final Future future = httpClient.execute(request, null);
            try {
                HttpResponse response = (HttpResponse) future.get();
                System.out.println("Response:" + request.getURI()+"; "+ response.getStatusLine());
                System.out.println("Shutting down");
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            }finally{
                try {
                    httpClient.close();
                } catch (IOException ex) {
                    System.out.println(ex.getMessage());
                }
            }
        long endTime = System.currentTimeMillis();

        System.out.println("執(zhí)行完畢, 耗時:"+(endTime-startTime)/1000+" 秒");
    }

多條url發(fā)送

 @Test
    public void moreRequest(){
        CloseableHttpAsyncClient httpClient =AsynHttpClientFactory.getCloseableHttpAsyncClient();
        long startTime = System.currentTimeMillis();
        final HttpGet[] requests = new HttpGet[10];
        for (int i = 0; i < requests.length; i++) {
            requests[i] = new HttpGet("http://www.apache.org/");
        }

        final CountDownLatch latch = new CountDownLatch(requests.length);
        for(final HttpGet request: requests){

            httpClient.execute(request, new FutureCallback(){
                @Override
                public void completed(Object obj) {
                    final HttpResponse response = (HttpResponse)obj;
                    latch.countDown();
                    System.out.println(request.getURI() + "->" + response.getStatusLine());
                }

                @Override
                public void failed(Exception excptn) {
                    latch.countDown();
                    System.out.println(request.getURI() + "->" + excptn);
                }

                @Override
                public void cancelled() {
                    latch.countDown();
                    System.out.println(request.getURI() + "cancelled");
                }
            });
        }

        try {
            latch.await();
            System.out.println("Shutting Down");
        } catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }finally{
            try {
                httpClient.close();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
        long endTime = System.currentTimeMillis();

        System.out.println("執(zhí)行完畢, 耗時:"+(endTime-startTime)/1000+" 秒");
    }
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市煌张,隨后出現(xiàn)的幾起案子呐赡,更是在濱河造成了極大的恐慌,老刑警劉巖骏融,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件链嘀,死亡現(xiàn)場離奇詭異,居然都是意外死亡档玻,警方通過查閱死者的電腦和手機怀泊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來误趴,“玉大人霹琼,你說我怎么就攤上這事×沟保” “怎么了枣申?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長看杭。 經(jīng)常有香客問我糯而,道長,這世上最難降的妖魔是什么泊窘? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮像寒,結果婚禮上烘豹,老公的妹妹穿的比我還像新娘。我一直安慰自己诺祸,他們只是感情好携悯,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筷笨,像睡著了一般憔鬼。 火紅的嫁衣襯著肌膚如雪龟劲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天轴或,我揣著相機與錄音昌跌,去河邊找鬼。 笑死照雁,一個胖子當著我的面吹牛蚕愤,可吹牛的內容都是我干的。 我是一名探鬼主播饺蚊,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼萍诱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了污呼?” 一聲冷哼從身側響起裕坊,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燕酷,沒想到半個月后籍凝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡悟狱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年静浴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挤渐。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡苹享,死狀恐怖,靈堂內的尸體忽然破棺而出浴麻,到底是詐尸還是另有隱情得问,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布软免,位于F島的核電站宫纬,受9級特大地震影響,放射性物質發(fā)生泄漏膏萧。R本人自食惡果不足惜漓骚,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榛泛。 院中可真熱鬧蝌蹂,春花似錦、人聲如沸曹锨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沛简。三九已至齐鲤,卻和暖如春斥废,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背给郊。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工牡肉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丑罪。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓荚板,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吩屹。 傳聞我的和親對象是個殘疾皇子跪另,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)煤搜,斷路器免绿,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,809評論 6 342
  • 總有一天你會明白,你的委屈要自己消化擦盾,你的故事不用逢人就講起嘲驾,真正理解你的人沒有幾個太多人只會站在他們自己的立場...
    7f1eb9ef276f閱讀 459評論 0 1
  • 姓名于欣榮 公司:遼寧叢迪服裝有限公司 【日精進打卡第81天】 【知~學習】 《大學》2遍 《通篇》1遍 【經(jīng)典...
    領悟人生123閱讀 82評論 0 0
  • 正值期末備考期,又到了大學生們突擊復習症见、熬夜備考的時候喂走。“晚上不睡谋作、早上不起”“越睡越晚”已經(jīng)成為眾多大學生的通病...
    歡樂大同閱讀 535評論 0 0