整合 okhttp
bean 容器
将 OkHttpClient 添加到 bean 容器
tio-boot 整合 okhttp 非常简单,只需要添加一个配置类将 okhttp3.OkHttpClient 放到 bean 容器中即可,配置示例如下
import java.util.concurrent.TimeUnit;
import com.litongjava.jfinal.aop.annotation.ABean;
import com.litongjava.jfinal.aop.annotation.AConfiguration;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
@AConfiguration
public class OkHttpClientConfig {
@ABean
public OkHttpClient config() {
Builder builder = new OkHttpClient().newBuilder();
// 连接池
builder.connectionPool(pool());
// 连接超时
builder.connectTimeout(120L, TimeUnit.SECONDS).readTimeout(120L, TimeUnit.SECONDS).build();
return builder.build();
}
private ConnectionPool pool() {
return new ConnectionPool(200, 5, TimeUnit.MINUTES);
}
}
为什么要将 OkHttpClient 添加到 bean 容器
将OkHttpClient
实例放入容器有多个好处,这种做法在开发大型应用时尤其重要。OkHttpClient
是一个能够处理 HTTP 请求的高效客户端,具有配置灵活、支持同步阻塞与异步处理 HTTP 请求等特点。以下是将OkHttpClient
放入容器中的几个主要理由:
重用连接和线程池:
OkHttpClient
实例在内部使用了连接池和线程池来优化资源使用和提高性能。通过将其作为单例(或者有限的几个实例)放入容器中,可以确保整个应用共享这些资源,避免了重复创建和销毁带来的开销,从而减少了内存占用和提高了性能。统一配置:将
OkHttpClient
配置在容器中可以让你在一个地方集中管理其配置,如超时设置、连接池大小等。这样做不仅使配置更加集中、易于管理,还能确保整个应用使用的是一致的 HTTP 客户端行为。对于需要调整 HTTP 行为以适应不同环境(开发、测试、生产)的情况,这一点尤其有用。便于维护和测试:通过依赖注入管理
OkHttpClient
,可以更容易地在不同的环境或测试场景下替换或模拟这个客户端。这对于编写单元测试和集成测试尤其重要,因为你可以注入一个配置了不同行为(如模拟服务器响应)的客户端,而不用改变测试代码外的实际代码。减少资源泄漏的风险:正确管理
OkHttpClient
实例(如通过容器确保其生命周期)有助于防止资源泄漏,例如忘记关闭连接。框架层面的管理有助于自动化这一过程,减少因错误使用 API 导致的问题。提高开发效率:最后,通过框架自动管理这些依赖项,开发者可以专注于业务逻辑而不是管理底层的 HTTP 通信细节,从而提高开发效率。
总的来说,将OkHttpClient
放入容器中是一种最佳实践,它有助于优化应用的性能和资源使用,同时提高了代码的可维护性和测试性。
单例枚举
单例枚举不依赖 bean 容器
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
public enum OkHttpClientPool {
INSTANCE;
static okhttp3.OkHttpClient.Builder builder;
static {
builder = new OkHttpClient().newBuilder();
// 连接池
builder.connectionPool(pool());
// 信任连接
builder.sslSocketFactory(sslSocketFactory(), x509TrustManager());
// 连接超时
builder.connectTimeout(120L, TimeUnit.SECONDS).readTimeout(120L, TimeUnit.SECONDS).build();
}
public static OkHttpClient getHttpClient() {
return builder.build();
}
private static ConnectionPool pool() {
return new ConnectionPool(200, 5, TimeUnit.MINUTES);
}
public static X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
public static SSLSocketFactory sslSocketFactory() {
try {
// 信任任何链接
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { x509TrustManager() }, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
}