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

cn.cliveyuan.tools.httpclient.client.OkHttpHttpClient Maven / Gradle / Ivy

The newest version!
package cn.cliveyuan.tools.httpclient.client;

import cn.cliveyuan.tools.common.MapTools;
import cn.cliveyuan.tools.common.StringTools;
import cn.cliveyuan.tools.httpclient.HttpClientSingleton;
import cn.cliveyuan.tools.httpclient.bean.HttpClientRequest;
import cn.cliveyuan.tools.httpclient.bean.HttpClientResponse;
import cn.cliveyuan.tools.httpclient.bean.RequestContextTypeEnum;
import cn.cliveyuan.tools.httpclient.bean.RequestMethodEnum;
import cn.cliveyuan.tools.httpclient.ssl.TrustAnySSL;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okio.BufferedSource;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * okHttp对httpClient的实现
 *
 * @author Clive Yuan
 * @date 2021/06/08
 */
@Slf4j
public class OkHttpHttpClient implements HttpClient {

    @Override
    public HttpClientResponse request(HttpClientRequest httpClientRequest) {
        HttpClientResponse httpClientResponse = new HttpClientResponse();
        httpClientResponse.setResponse(StringTools.EMPTY);
        OkHttpClient okHttpClient = buildOkHttpClient(httpClientRequest);
        HttpUrl httpUrl = getHttpUrl(httpClientRequest.getMethod(), httpClientRequest.getUrl(), httpClientRequest.getParams());
        RequestBody requestBody = null;
        if (!RequestMethodEnum.GET.equals(httpClientRequest.getMethod())) {
            requestBody = this.buildRequestBody(httpClientRequest);
        }
        final Request.Builder requestBuilder = new Request.Builder().method(httpClientRequest.getMethod().name(), requestBody).url(httpUrl);
        log.debug("HttpClient request: {}", httpClientRequest);
        Request request = buildRequest(requestBuilder, httpClientRequest.getHeaders());
        Call call = okHttpClient.newCall(request);
        try (Response response = call.execute()) {
            httpClientResponse.setStatusCode(response.code());
            httpClientResponse.setSuccessful(response.isSuccessful());
            ResponseBody responseBody = response.body();
            if (Objects.nonNull(responseBody)) {
                httpClientResponse.setResponse(this.handleResponse(httpClientRequest, responseBody));
            }
            Headers headers = response.headers();
            httpClientResponse.setHeaders(getResponseHeaders(headers));
            httpClientResponse.setCookies(getResponseCookies(headers));
        } catch (Exception e) {
            log.error("request error: httpClientRequest=" + httpClientRequest, e);
            throw new RuntimeException(e);
        }
        log.debug("HttpClient response: {}", httpClientResponse);
        return httpClientResponse;
    }

    private RequestBody buildRequestBody(HttpClientRequest httpClientRequest) {
        if (RequestContextTypeEnum.JSON.equals(httpClientRequest.getContextType())) {
            return RequestBody.create(httpClientRequest.getContextType().getMediaType(), httpClientRequest.getRequestBody());
        }
        Map params = httpClientRequest.getParams();
        FormBody.Builder formBodyBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
        if (MapTools.isNotEmpty(params)) {
            params.forEach((key, value) -> {
                if (Objects.isNull(key) || Objects.isNull(value)) {
                    return;
                }
                formBodyBuilder.add(key, value.toString());
            });

        }
        return formBodyBuilder.build();
    }

    private OkHttpClient buildOkHttpClient(HttpClientRequest httpClientRequest) {
        OkHttpClient okHttpClient = HttpClientSingleton.getOkHttpClient();
        if (httpClientRequest.getConnectTimeout() != null
                || httpClientRequest.getReadTimeout() != null
                || httpClientRequest.getWriteTimeout() != null
                || httpClientRequest.getCustomizedBuilderConsumer() != null
                || httpClientRequest.isIgnoreSslCertificate()) {
            OkHttpClient.Builder builder = okHttpClient.newBuilder();
            if (Objects.nonNull(httpClientRequest.getConnectTimeout())) {
                builder.connectTimeout(httpClientRequest.getConnectTimeout());
            }
            if (Objects.nonNull(httpClientRequest.getReadTimeout())) {
                builder.readTimeout(httpClientRequest.getReadTimeout());
            }
            if (Objects.nonNull(httpClientRequest.getWriteTimeout())) {
                builder.writeTimeout(httpClientRequest.getWriteTimeout());
            }
            if (httpClientRequest.isIgnoreSslCertificate()) {
                builder.sslSocketFactory(TrustAnySSL.sslSocketFactory, TrustAnySSL.x509TrustManager)
                        .hostnameVerifier(TrustAnySSL.hostnameVerifier);
            }
            if (Objects.nonNull(httpClientRequest.getCustomizedBuilderConsumer())) {
                httpClientRequest.getCustomizedBuilderConsumer().accept(builder);
            }
            return builder.build();
        }
        return okHttpClient;
    }

    private String handleResponse(HttpClientRequest httpClientRequest, ResponseBody responseBody) throws IOException {
        if (Objects.nonNull(httpClientRequest.getCharset())) {
            try (BufferedSource source = responseBody.source()) {
                Charset charset = Util.readBomAsCharset(source, httpClientRequest.getCharset());
                return source.readString(charset);
            }
        }
        return responseBody.string();
    }

    private Map getResponseCookies(Headers headers) {
        Map cookieMap = new HashMap<>();
        String cookieString = headers.get("Set-Cookie");
        if (Objects.nonNull(cookieString)) {
            String[] pairs = cookieString.split(";");
            for (String pair : pairs) {
                String[] kvs = pair.split("=");
                String key = kvs[0].trim();
                StringJoiner value = new StringJoiner("");
                if (kvs.length >= 2) {
                    for (int i = 1; i < kvs.length; i++) {
                        value.add(kvs[i]);
                    }
                }
                cookieMap.put(key, value.toString());
            }
        }
        return cookieMap;
    }

    private Map getResponseHeaders(Headers headers) {
        Map headerMap = new HashMap<>();
        for (int i = 0; i < headers.size(); i++) {
            String name = headers.name(i);
            headerMap.put(name, headers.get(name));
        }
        return headerMap;
    }

    private static Request buildRequest(Request.Builder requestBuilder, Map headers) {
        if (!headers.isEmpty()) {
            headers.forEach((key, value) -> {
                if (key != null && value != null) {
                    requestBuilder.addHeader(key, value);
                }
            });
        }
        return requestBuilder.build();
    }


    private static HttpUrl getHttpUrl(RequestMethodEnum method, String url, Map params) {
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (RequestMethodEnum.GET.equals(method) && httpUrl != null && MapTools.isNotEmpty(params)) {
            final HttpUrl.Builder httpUrlBuilder = httpUrl.newBuilder();
            params.forEach((key, value) -> {
                if (key != null && value != null) {
                    httpUrlBuilder.addQueryParameter(key, String.valueOf(value));
                }
            });
            return httpUrlBuilder.build();
        }
        return httpUrl;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy