org.eu.vooo.commons.net.client.HttpClient Maven / Gradle / Ivy
package org.eu.vooo.commons.net.client;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;
import org.apache.commons.lang3.StringUtils;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @author [email protected]
*/
public class HttpClient {
private static final String HTTP = "http";
private static final String HTTPS = "https";
private static final Integer HTTP_DEFAULT_PORT = 80;
private static final Integer HTTPS_DEFAULT_PORT = 443;
private final Retrofit retrofit;
private HttpClient(HttpClientBuilder builder) {
this.retrofit = builder.retrofit;
}
public T createService(Class T) {
return this.retrofit.create(T);
}
public static class HttpClientBuilder {
private Retrofit retrofit;
private OkHttpClient okHttpClient;
private HttpLoggingInterceptor loggingInterceptor;
private ConnectionSpec connectionSpec;
private Long timeout = 180L;
private String protocol;
private String host;
private Integer port = 80;
private String context;
private String baseUrl;
private String[] headers;
private boolean debug;
public HttpClientBuilder timeout(Long timeout) {
this.timeout = timeout;
return this;
}
public HttpClientBuilder protocol(String protocol) {
this.protocol = protocol;
return this;
}
public HttpClientBuilder host(String host) {
this.host = host;
return this;
}
public HttpClientBuilder port(Integer port) {
this.port = port;
return this;
}
public HttpClientBuilder context(String context) {
this.context = context;
return this;
}
public HttpClientBuilder baseUrl(String baseUrl) {
this.baseUrl = baseUrl;
return this;
}
public HttpClientBuilder header(String[] headers) {
this.headers = headers;
return this;
}
public HttpClientBuilder debug(boolean debug) {
this.debug = debug;
return this;
}
private void init() {
initConnectionSpec();
initLoggingInterceptor();
initOkhttpClient();
initRetrofit();
}
private void initRetrofit() {
StringBuilder baseUrlBuilder = new StringBuilder();
baseUrlBuilder.append(this.protocol).append("://");
baseUrlBuilder.append(this.host);
if (!port.equals(HTTP_DEFAULT_PORT) && !port.equals(HTTPS_DEFAULT_PORT)) {
baseUrlBuilder.append(":").append(port);
}
baseUrlBuilder.append(this.context);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
mapper.configure(MapperFeature.AUTO_DETECT_SETTERS, false);
mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mapper.setVisibility(mapper.getSerializationConfig()
.getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY));
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(StringUtils.isNotBlank(baseUrl) ? baseUrl : baseUrlBuilder.toString())
.client(this.okHttpClient)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.addConverterFactory(ScalarsConverterFactory.create());
this.retrofit = builder.build();
}
private void initOkhttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(this.timeout, TimeUnit.SECONDS)
.readTimeout(this.timeout, TimeUnit.SECONDS)
.writeTimeout(this.timeout, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder();
if (Objects.nonNull(headers)) {
for (String header : headers) {
if (header.split(":").length < 2) {
requestBuilder.removeHeader(header.split(":")[0]);
continue;
}
requestBuilder.header(header.split(":")[0],
header.split(":")[1]);
}
}
Request request = requestBuilder
.method(original.method(), original.body())
.build();
return chain.proceed(request);
})
.addInterceptor(new TimeoutInterceptor());
if (Objects.nonNull(this.connectionSpec)) {
builder.connectionSpecs(Collections.singletonList(this.connectionSpec));
}
if (Objects.nonNull(this.loggingInterceptor)) {
builder.addInterceptor(this.loggingInterceptor);
}
this.okHttpClient = builder.build();
}
private void initLoggingInterceptor() {
if (debug) {
this.loggingInterceptor = new HttpLoggingInterceptor();
this.loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
}
}
private void initConnectionSpec() {
if ((StringUtils.isNotBlank(this.baseUrl) && this.baseUrl.contains(HTTPS)) || HTTPS.equals(this.protocol)) {
this.connectionSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
.build();
}
}
public HttpClient build() {
init();
return new HttpClient(this);
}
}
}