参考
简介
okhttp是一个高效的http客户端,支持ipv4+ipv6,TLS,多ip选择
1、支持HTTP/2多个请求共享一个socket
2、连接池的使用,减少不必要的请求
3、gzip大小压缩
4、请求结果缓存,减少重复请求(所有OkHttpClient 的实例应该只有一个,否则缓存冲突)
依赖
Android 5.0+ (API level 21+) 、 Java 8+ 、 Okio
implementation("com.squareup.okhttp3:okhttp:4.0.1")
使用
1、请求client
OkHttpClient client = new OkHttpClient();
2、请求request
get
Request request = new Request.Builder().url(url).build();
post
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder().url(url).post(body).build();
3、执行
同步执行
client.newCall(request).execute()
response.isSuccessful()
response.body().string()
异步执行
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
}
@Override public void onResponse(Call call, Response response) throws IOException {
}
});
其它方法
添加或者获取头信息
header(name, value): 前面存在name,则重新设置值
addHeader(name, value):无论前面是否存在name,添加当前值对
header(name): 获取name对应的value,无值,返回null
请求体为流、File对象、字符串
MediaType MEDIA_TYPE_MARKDOWN= MediaType.parse("text/x-markdown; charset=utf-8");
post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
postBody为字符串,File对象,流;为流时,需要实现下面两个方法
RequestBody requestBody = new RequestBody() {
@Override public MediaType contentType() {
return MEDIA_TYPE_MARKDOWN;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
}
};
请求体为值对
RequestBody formBody = new FormBody.Builder().add("search", "Jurassic Park").build();
json数据
RequestBody body = RequestBody.create(JSON, json);
请求体多类别
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "Square Logo")
.addFormDataPart("image", "logo-square.png", RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();
请求结果缓存时长
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
超时
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
授权验证
client = new OkHttpClient.Builder()
.authenticator(new Authenticator() {
@Override public Request authenticate(Route route, Response response) throws IOException {
if (response.request().header("Authorization") != null) {
return null; // Give up, we've already attempted to authenticate.
}
String credential = Credentials.basic("jesse", "password1");
return response.request().newBuilder().header("Authorization", credential).build();
}
})
.build();
拦截器
一个强有力的机制,可以重写,重新请求、检测请求的机制;多个拦截器之间按顺序执行
1、书写拦截器
class LoggingInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
return response;
}
}
2、添加拦截器
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
网络拦截器使用 addNetworkInterceptor()添加
HTTPS
设置TLS安全规格
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS))
.build();
优先列表中第一个规格,失败选择后一个规格
自己设置选择
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec))
.build();
设置证书
client = new OkHttpClient.Builder()
.certificatePinner(new CertificatePinner.Builder().add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=").build())
.build();
受信任的证书
SSLContext sslContext = sslContextForTrustedCertificates(trustedCertificatesInputStream());
client = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory())
.build();
监听请求过程 EventListener
OkHttpClient client = new OkHttpClient.Builder()
.eventListener(new PrintingEventListener())
.build();