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;
}
}