HTTP是现代应用程序网络的方式。这就是我们交换数据和媒体的方式。有效地执行 HTTP 会使内容加载速度更快并节省带宽。
OkHttp 是一个默认高效的 HTTP 客户端:
- HTTP/2 支持允许对同一主机的所有请求共享一个套接字。
- 连接池可减少请求延迟(如果 HTTP/2 不可用)。
- 透明 GZIP 可缩小下载大小。
- 响应缓存完全避免了重复请求的网络。
OkHttp在网络遇到麻烦时会坚持下去:它将从常见的连接问题中静默地恢复。如果您的服务有多个 IP 地址,则在第一次连接失败时,OkHttp 将尝试备用地址。这对于 IPv4+IPv6 和托管在冗余数据中心的服务是必需的。OkHttp 支持现代 TLS 功能(TLS 1.3、ALPN、证书固定)。可以将其配置为回退以实现广泛的连接。
使用 OkHttp 很容易。它的请求/响应API设计有流畅的构建器和不可变性。它支持同步阻塞调用和带回调的异步调用。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@Slf4j
public class HttpTools {
private static volatile HttpTools instance = new HttpTools();
private HttpTools() {
}
public static HttpTools getInstance() {
return instance;
}
/**
* @return
*/
private static OkHttpClient getHttpClient() {
OkHttpClient eagerClient = new OkHttpClient().newBuilder()
.readTimeout(10000, TimeUnit.MILLISECONDS)
.build();
return eagerClient;
}
/**
* @param url
* @param requestBody
* @return
*/
public static String post(String url, String requestBody) {
String responseInfo = "";
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(mediaType, requestBody))
.build();
try {
Response response = getHttpClient().newCall(request).execute();
responseInfo = response.body().string().toString();
} catch (IOException ex) {
log.error("HttpTools err = ", ex);
}
return responseInfo;
}
/**
* @param url
* @param requestBody
* @return
*/
public static String postWithHeader(String url, String requestBody, String requestHeader) {
String responseInfo = "";
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
Request request = new Request.Builder()
.url(url)
.addHeader("token", requestHeader)
.post(RequestBody.create(mediaType, requestBody))
.build();
try {
Response response = getHttpClient().newCall(request).execute();
responseInfo = response.body().string().toString();
} catch (IOException ex) {
log.error("HttpTools err = ", ex);
}
return responseInfo;
}
/**
* @param url
* @return
*/
public static String get(String url) {
String responseInfo = "";
Request request = new Request.Builder()
.url(url)
.get()
.build();
try {
Response response = getHttpClient().newCall(request).execute();
responseInfo = response.body().string().toString();
} catch (IOException ex) {
log.error("HttpTools err = ", ex);
}
return responseInfo;
}
private OkHttpClient getHttpsClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(10000, TimeUnit.MICROSECONDS);
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
try {
trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
builder.sslSocketFactory(sslSocketFactory, trustManager);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Certificate[] localCertificates = new Certificate[0];
try {
//获取证书链中的所有证书
localCertificates = session.getPeerCertificates();
} catch (SSLPeerUnverifiedException e) {
e.printStackTrace();
}
//打印所有证书内容
for (Certificate c : localCertificates) {
log.debug("verify: " + c.toString());
}
return true;
}
});
return builder.build();
}
private InputStream trustedCertificatesInputStream() {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(
"src/main/java/com/tencent/healthdc/dragonboat/util/DigiCert Global Root CA.cer");
} catch (IOException e) {
e.printStackTrace();
}
return inputStream;
}
private X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
char[] password = "password".toCharArray();
// Put the certificates a key store.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
log.debug("trustManagerForCertificates: " + certificate.toString());
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = null;
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
}