HttpClientManager

时间:2022-11-24
本文章向大家介绍HttpClientManager,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

HttpClientManger

package com.gateway.http.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.apollo.common.http.HttpMethod;
import com.apollo.gateway.common.HttpConstant;
import com.apollo.gateway.util.JsonUtil;
import okhttp3.*;
import okhttp3.internal.Util;
import okhttp3.logging.HttpLoggingInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Copyright 2022 NVXClouds Inc. All Rights Reserved.
 *
 * @author muzhi
 * @date 2022-11-21 19:17:28
 */
public class HttpClientManager {
    private static final Logger log = LoggerFactory.getLogger(HttpClientManager.class);
    private static final Map<Long, OkHttpClient> map = new HashMap<>();
    private static final Long TIMEOUT = 5000L;
    private <T> T request(HttpMethod httpMethod, OkHttpClient httpClient, final String url, Map<String, String> header, final Object param,
                          final TypeReference<T> typeReference) throws IOException {
        final Request.Builder builder = new Request.Builder();
        //add header
        if(header != null && !header.isEmpty()){
            header.forEach((k, v) -> {
                if(v != null){
                    builder.addHeader(k, v);
                }
            });
        }

        switch (httpMethod){
            case POST:
                if(param != null){
                    if(param instanceof byte[]){
                        builder.post(new ByteRequestBody((byte[]) param));
                    } else {
                        String content = JsonUtil.toJson(param);
                        RequestBody requestBody = RequestBody.create(HttpConstant.JSON_MEDIA_TYPE, content);
                        builder.post(requestBody);
                    }
                } else {
                    builder.post(RequestBody.create(HttpConstant.JSON_MEDIA_TYPE, "{}"));
                }
                builder.url(url);
                break;
            case GET:
                StringBuilder str = new StringBuilder(url);
                if(param != null && param instanceof Map){
                    if(!url.contains("?")){
                        str.append("?");
                    }
                    Map body = (Map) param;
                    if(body != null && !body.isEmpty()){
                        StringJoiner joiner = new StringJoiner("", "&", "");
                        body.forEach((k, v) -> {
                            joiner.add(k + "=" + v);
                        });
                        str.append("&").append(joiner.toString());
                    }
                }
                builder.url(str.toString()).get();
                break;
            default:
                throw new RuntimeException("request method not supported");
        }

        Response execute = httpClient.newCall(builder.build()).execute();
        String response = execute.body().string();
        if(typeReference == null){
            return (T) response;
        }
        return JsonUtil.readValue(response, typeReference);
    }


    private  <T> T request(HttpMethod httpMethod, final String accessCode, final String url, final Object param,
                           final TypeReference<T> typeReference) throws IOException {
        OkHttpClient httpClient = map.computeIfAbsent(TIMEOUT, k -> buildHttpClient());
        Map<String, String> header = new HashMap<>();
        return request(httpMethod, httpClient, url, header, param, typeReference);
    }

//    public <T> T post(final String accessCode, final String url, final Object param,
//                      final TypeReference<T> typeReference, Long timeout) throws IOException {
//        return request(HttpMethod.POST, accessCode, url, param, typeReference, timeout);
//    }

    public <T> T post(final String accessCode, final String url, final Object param,
                      final TypeReference<T> typeReference) throws IOException {
        return request(HttpMethod.POST, accessCode, url, param, typeReference);
    }

    private OkHttpClient buildHttpClient() {
        try {
            OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
            // add timeout
            okHttpBuilder
                .readTimeout(60_000, TimeUnit.MILLISECONDS)
                .connectTimeout(60_000, TimeUnit.MILLISECONDS)
                .callTimeout(60_000, TimeUnit.MILLISECONDS)
                .connectionPool(new ConnectionPool(500, 5 * 60, TimeUnit.SECONDS)); // Install the all-trusting trust manager
            //okHttpBuilder.addInterceptor(new RetryInterceptor(httpClientParam.getMaxRetry(), httpClientParam.getRetryInterval()));
            configNoSSL(okHttpBuilder);
            configDispatcher(okHttpBuilder);
            configLogBody(okHttpBuilder, true);
            return okHttpBuilder.build();
        } catch (Exception e) {
            log.error("buildHttpClient error", e);
        }
        return null;
    }

    private void configDispatcher(final OkHttpClient.Builder okHttpBuilder) {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
            new SynchronousQueue<>(),
            Util.threadFactory("lambada-OkHttp-Dispatcher", false)
        );
        Dispatcher dispatcher = new Dispatcher(executorService);
        dispatcher.setMaxRequests(200);
        dispatcher.setMaxRequestsPerHost(200);
        okHttpBuilder.dispatcher(dispatcher);
    }

    private static void configLogBody(OkHttpClient.Builder okHttpBuilder, boolean ignoreLargeContent) {
        HttpLogger logger = new HttpLogger();
        logger.setIgnoreLargeContent(ignoreLargeContent);
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(logger);
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        okHttpBuilder.addNetworkInterceptor(logInterceptor);
    }

    private static void configNoSSL(OkHttpClient.Builder okHttpBuilder) throws KeyManagementException, NoSuchAlgorithmException {
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new SecureRandom());
        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        okHttpBuilder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
        okHttpBuilder.hostnameVerifier((hostname, session) -> true);
    }

    private static final TrustManager[] trustAllCerts =
        new TrustManager[] {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] chain, String authType) {
                }

                @Override
                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] chain, String authType) {
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[] {};
                }
            }
        };
}

原文地址:https://www.cnblogs.com/exmyth/p/16922937.html