All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ksyun.pnp.sdk.util.http.HttpClientUtil Maven / Gradle / Ivy

package com.ksyun.pnp.sdk.util.http;

import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * httpclient util
 */
public final class HttpClientUtil {

    private static final String DEFAULT_USER_AGENT = "kingsoft-pnp-httpclient";
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);

    private static final int midTimeout = 5000;

    private static final int maxRequests = 250;
    private static final int maxRequestPerHost = 200;

    public static final String CONTENT_TYPE = "Content-Type";
    public static final String APPLICATION_JSON = "application/json";
    public static final String ACCEPT = "Accept";

    private static final String USER_AGENT = "User-Agent";

    private static OkHttpClient midHttpClient;
    // for overseas http/https calls

    private static Map defaultHeader = null;

    static {
        OkHttpClient.Builder midBuilder = new OkHttpClient.Builder();

        midBuilder.connectTimeout(midTimeout, TimeUnit.MILLISECONDS)
                .readTimeout(midTimeout, TimeUnit.MILLISECONDS)
                .writeTimeout(midTimeout, TimeUnit.MILLISECONDS);
        midHttpClient = midBuilder.build();
        midHttpClient.dispatcher().setMaxRequests(maxRequests);
        midHttpClient.dispatcher().setMaxRequestsPerHost(maxRequestPerHost);

        Map tmpDefaultHeaderMap = new HashMap<>();
        tmpDefaultHeaderMap.put(USER_AGENT, DEFAULT_USER_AGENT);
        defaultHeader = Collections.unmodifiableMap(tmpDefaultHeaderMap);
    }

    public static void setMidHttpClient(OkHttpClient customClient) {
        HttpClientUtil.midHttpClient = customClient;
    }

    public static SimpleHttpResponse get(String url) {
        return get(getURL(url), null, findDefaultHttpClient());
    }


    /**
     * get url with specified headers
     *
     * @param url     the specified url
     * @param headers the request http headers
     * @return SimpleHttpResponse
     */
    public static SimpleHttpResponse get(String url, Map headers) {
        return get(getURL(url), headers, findDefaultHttpClient());
    }

    /**
     * post parameterMap as "application/x-www-form-urlencoded"
     *
     * @param url          the specified url
     * @param headers      http request headers
     * @param parameterMap http post parameters
     * @return SimpleHttpResponse
     */
    public static SimpleHttpResponse post(String url, Map headers, Map parameterMap) {
        return post(getURL(url), headers, parameterMap, findDefaultHttpClient());
    }

    public static SimpleHttpResponse postRawBody(String url, Map headers, String body) {
        return postRawBody(getURL(url), headers, body);
    }

    /**
     * the real get api,
     *
     * @param url     the specified url
     * @param headers the http request headers
     * @return SimpleHttpResponse
     */
    public static SimpleHttpResponse get(URL url, Map headers, OkHttpClient client) {
        Map finalHeaders = new HashMap<>(defaultHeader);
        if (headers != null) {
            finalHeaders.putAll(headers);
        }
        Headers h = Headers.of(finalHeaders);
        Request req = new Request.Builder().url(url).headers(h).build();
        return doCall(client, req);
    }

    /**
     * post parameterMap as "application/x-www-form-urlencoded"
     *
     * @param url          the specified url
     * @param headers      http request headers
     * @param parameterMap http post parameters
     * @return SimpleHttpResponse
     */
    public static SimpleHttpResponse post(URL url, Map headers, Map parameterMap,
                                          OkHttpClient client) {
        if (parameterMap == null) {
            parameterMap = new HashMap<>();
        }
        Map finalHeaders = new HashMap<>(defaultHeader);

        if (headers != null) {
            finalHeaders.putAll(headers);
        }

        FormBody.Builder fbBuilder = new FormBody.Builder();
        for (Map.Entry entry : parameterMap.entrySet()) {
            fbBuilder.add(entry.getKey(), entry.getValue());
        }
        RequestBody body = fbBuilder.build();
        Request.Builder builder = new Request.Builder().headers(Headers.of(finalHeaders)).url(url).post(body);

        Request req = builder.build();
        return doCall(client, req);
    }


    /**
     * transform the checked exception to runtime exception
     *
     * @param url the specified String url
     * @return URL Object
     */
    private static URL getURL(String url) {
        URL u;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            LOGGER.warn("try getContent with Malformed URL {}", url);
            throw new RuntimeException("url error: " + url, e);
        }
        return u;
    }

    private static SimpleHttpResponse doCall(OkHttpClient client, Request req) {
        long start = Instant.now().toEpochMilli();
        boolean succ = false;
        long size = 0;
        SimpleHttpResponse response;

        try {
            Response res = client.newCall(req).execute();

            succ = res.isSuccessful();
            size = res.body() == null ? 0 : res.body().contentLength();

            response = SimpleHttpResponse.newHttpResponse(res);
            return response;
        } catch (IOException e) {
            LOGGER.warn("OkHttpClient {} request {}", client, req, e);
            response = SimpleHttpResponse.Error(e);
            return response;
        } finally {
            long cost = Instant.now().toEpochMilli() - start;
            LOGGER.info("http call success[{}] url[{}] method[{}] costMills[{}] size[{}] ", succ, req.url().url().toString(), req.method(), cost, size);
        }
    }

    /**
     * post body as raw data
     *
     * @param url     the specified url
     * @param headers http request headers
     * @param body    http post body raw data ,the default body type is json or specified in headers Content-type field
     * @return SimpleHttpResponse
     */
    private static SimpleHttpResponse postRawBody(URL url, Map headers, String body) {
        OkHttpClient client = findDefaultHttpClient();

        Map finalHeaders = new HashMap<>(defaultHeader);

        if (headers != null) {
            finalHeaders.putAll(headers);
        }

        // rare condition: post nothing to an url
        if (body == null) {
            body = StringUtils.EMPTY;
        }
        String type = finalHeaders.getOrDefault(CONTENT_TYPE, APPLICATION_JSON);
        RequestBody requestBody = RequestBody.create(MediaType.parse(type), body.getBytes(StandardCharsets.UTF_8));
        Request.Builder builder = new Request.Builder().headers(Headers.of(finalHeaders)).url(url).post(requestBody);

        Request req = builder.build();
        return doCall(client, req);
    }


    /**
     * auto find best client for url
     *
     * @return the best http client
     */
    private static OkHttpClient findDefaultHttpClient() {
        return midHttpClient;
    }
}
/* iNmConn0uip70crikacRLqPNiGu8mGjF3ZurXThex0Ad7+N3jCPF9OPT6jyQABS8zRq79S1d8ZYjXwxrHuip/hjNPe8f2qPPyLUhKzVpzidSWjBZCgIehjG+ijE61XQPollYf7fPLd4HenAQekZeNA0ZBxM1G256yUr/bsiMfDw= */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy