OKhttp使用详解(二)
发布日期:2025-04-28 00:27:44 浏览次数:20 分类:精选文章

本文共 5556 字,大约阅读时间需要 18 分钟。

OkHttp技术深入解析

Cookie保存

Cookie的保存为应用程序提供了便捷的状态管理方式,常见的实现方式包括使用SharedPreferences存储。以下是OkHttp中CookieJar的实现示例:

OkHttpClient okHttpClient = new OkHttpClient.Builder()    .cookieJar(new CookieJar() {        @Override        public void saveFromResponse(HttpUrl url, List
cookies) { // 保存cookie通常使用SharedPreferences } @Override public List
loadForRequest(HttpUrl url) { // 从保存位置读取,注意此处不能为空,否则会导致空指针 return new ArrayList<>(); } }) .build();

Websocket

OkHttp支持WebSocket协议,适用于简易推送和长时间连接。WebSocket首先通过HTTP握手建立连接,成功后切换到长连接模式,类似于心跳机制。以下是一个简单的WebSocket实现示例:

OkHttpClient okHttpClient = new OkHttpClient.Builder()    .build();Request request = new Request.Builder()    .url("https://wwww.xxx.com")    .build();okHttpClient.newWebSocket(request, new WebSocketListener() {    @Override    public void onMessage(WebSocket webSocket, String text) {        // 收到文本消息    }    @Override    public void onOpen(WebSocket webSocket, Response response) {        // 连接成功    }    @Override    public void onMessage(WebSocket webSocket, ByteString bytes) {        // 收到字节消息,可转换为文本    }    @Override    public void onClosed(WebSocket webSocket, int code, String reason) {        // 连接被关闭    }    @Override    public void onFailure(WebSocket webSocket, Throwable t, Response response) {        // 连接失败    }});

拦截器

拦截器是一种强大的机制,允许我们监控、重写和重试HTTP请求。以下是一个简单的拦截器实现,用于记录请求和响应信息:

public class LoggingInterceptor implements Interceptor {    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        long t1 = System.nanoTime();        System.out.println("请求信息:发送时间>> " + t1 + " >> " + chain.connection() + " headers>> " + request.headers());        Response response = chain.proceed(request);        long t2 = System.nanoTime();        System.out.println("花费时间:" + (t2 - t1) + "响应信息>> ");        return response;    }}

添加拦截器

应用拦截器

builder.addInterceptor(new LoggingInterceptor());

网络拦截器

builder.addInterceptor(new LoggingInterceptor());

拦截器的优点

应用拦截器

  • 不必担心中间响应(如重定向和重试)
  • 总是调用一次,即使从缓存中提供HTTP响应
  • 遵守应用程序的原始意图
  • 允许短路或多次调用chain.proceed()
  • 允许重试

网络拦截器

  • 能够处理重定向和重试等中间响应
  • 对缓存网络短路的响应不被调用
  • 可以观察数据,如网络传输一样
  • 访问带有请求的连接

拦截器的应用场景

修改请求

拦截器可以修改请求头和请求体。例如,以下是一个用于压缩请求体的拦截器:

final class GzipRequestInterceptor implements Interceptor {    @Override    public Response intercept(Interceptor.Chain chain) throws IOException {        Request originalRequest = chain.request();        if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {            return chain.proceed(originalRequest);        }        Request compressedRequest = originalRequest.newBuilder()            .header("Content-Encoding", "gzip")            .method(originalRequest.method(), gzip(originalRequest.body()))            .build();        return chain.proceed(compressedRequest);    }    private RequestBody gzip(RequestBody body) {        return new RequestBody() {            @Override            public MediaType contentType() {                return body.contentType();            }            @Override            public long contentLength() {                return -1; // 未知压缩后的长度            }            @Override            public void writeTo(BufferedSink sink) throws IOException {                BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));                body.writeTo(gzipSink);                gzipSink.close();            }        };    }}

修改响应

拦截器也可以修改响应。以下是一个用于修复Cache-Control响应头的拦截器:

private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {    @Override    public Response intercept(Interceptor.Chain chain) throws IOException {        Response originalResponse = chain.proceed(chain.request());        return originalResponse.newBuilder()            .header("Cache-Control", "max-age=60")            .build();    }};

HTTPS

OkHttp默认使用现代TLS配置,若失败则使用兼容性TLS。以下是一个自定义TLS配置的示例:

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();

证书管理

信任固定

默认情况下,OkHttp信任主机平台的证书颁发机构。以下是一个自定义信任证书的示例:

client = new OkHttpClient.Builder()    .certificatePinner(new CertificatePinner.Builder()        .add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")        .build())    .build();

自定义信任存储

private final OkHttpClient client;public CustomTrust() {    SSLContext sslContext = sslContextForTrustedCertificates(trustedCertificatesInputStream());    client = new OkHttpClient.Builder()        .sslSocketFactory(sslContext.getSocketFactory())        .build();}public void run() throws Exception {    Request request = new Request.Builder()        .url("https://publicobject.com/helloworld.txt")        .build();    Response response = client.newCall(request).execute();    System.out.println(response.body().string());}// 其他方法(如获取受信任证书存储)省略

常用工具

  • Chuck:Android的HTTP客户端,支持检查器
  • Fresco:Android图像管理库,专注于内存管理
  • Glide:Android图像加载和缓存库,支持滚动加载
  • Moshi:Android的JSON解析库
  • Ok2Curl:OkHttp拦截器,用于打印日志
  • okhttp-digedt:OkHttp摘要验证器
  • okhttp-signpost:OkHttp签名请求扩展
  • Oklog:便于查看日志的库
  • PersistentCookieJar:基于SharedPreferences的持久CookieJar实现
  • Picasso:Android图像下载和缓存库
  • Retrofit:Square和Inc.的类型安全HTTP客户端
  • Stetho:Android应用调试工具
  • Wire:轻量级协议缓冲区工具

以上就是对OkHttp技术的深入解析,希望能为开发提供参考。

上一篇:Okhttp拦截器
下一篇:OkHttp使用详解

发表评论

最新留言

关注你微信了!
[***.104.42.241]2026年06月15日 17时13分36秒