Okhttp介紹及使用


Okhttp簡介

HTTP是現代應用常用的一種交換數據和媒體的網絡方式,高效地使用HTTP能讓資源加載更快,節省帶寬。OkHttp是一個高效的HTTP客戶端,它有以下默認特性:

  • 支持HTTP/2,允許所有同一個主機地址的請求共享同一個socket連接
  • 連接池減少請求延時
  • 透明的GZIP壓縮減少響應數據的大小
  • 緩存響應內容,避免一些完全重復的請求

當網絡出現問題的時候OkHttp依然堅守自己的職責,它會自動恢復一般的連接問題,如果你的服務有多個IP地址,當第一個IP請求失敗時,OkHttp會交替嘗試你配置的其他IP,OkHttp使用現代TLS技術(SNI, ALPN)初始化新的連接,當握手失敗時會回退到TLS 1.0。

OkHttp官網地址: http://square.github.io/okhttp/

pom依賴:

<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.7.2</version>
</dependency>

Okhttp使用

本文使用的OkHttp版本為4.7.2。OkHttp的核心類主要有OkHttpClient,Dispatcher,Call,Request,Response,Interceptor,Chain。其中OkHttpClient是負責管理多個Call的組織者,而每個Call又包含一個Request和Response,並且Call中的回調用於提供響應結果。要完成一次網絡請求,我們需要告訴Call需要處理的Request是什么樣的,例如它的URL是什么,然后將Call交給OkHttpClient。OkHttpClient僅對本次請求做一些配置,例如指定緩存路徑,它會讓Dispatcher去決定何時執行Call。而Dispatcher的底層實現就是一個由OkHttp默認實現的線程池,它將最終執行Call中的.run()方法。最后的Interceptor和Chain將用於數據的攔截處理。OkHttp提供兩種方式提交網絡請求,分別是Call.execute()和Call.enqueue(Callback),前者會阻塞線程,后者加入隊列異步執行。通過調用response.body().string()我們可以得到響應的body部分並以String形式返回,但值得注意的是.string()只能調用一次。

創建並配置OkHttpClient 

基礎配置

/**
 * OkHttpClient是通過OkHttpClient.Builder來配置參數的。
 */
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//設置連接超時
builder.connectTimeout(30, TimeUnit.SECONDS);
//設置讀超時
builder.readTimeout(30, TimeUnit.SECONDS);
//設置寫超時
builder.writeTimeout(30, TimeUnit.SECONDS);
//是否自動重連
builder.retryOnConnectionFailure(true);

//......其他配置

//創建OkHttpClient客戶端,一般一個項目可以將OkHttpClient設置成單例
OkHttpClient okHttpClient = builder.build();

其他配置

//從調用call.execute();和enqueue();這兩個方法開始計時,時間到后網絡還未請求完成將調用cancel();方法
builder.callTimeout(10, TimeUnit.SECONDS);
//只有http2和webSocket中有使用,如果設置了這個值會定時的向服務器發送一個消息來保持長連接
builder.pingInterval(10, TimeUnit.SECONDS);

1、添加攔截器

builder.addInterceptor(new LoggingInterceptor());

LoggingInterceptor.java

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

import java.io.IOException;

/**
 * 請求攔截器
 * 打印OKHttp請求日志
 */
public class LoggingInterceptor implements Interceptor {

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        //這個chain里面包含了request和response,所以你要什么都可以從這里拿
        Request request = chain.request();

        long t1 = System.nanoTime();//請求發起的時間
        System.out.println(String.format("發送請求 %s on %s%n%s",
                request.url(), chain.connection(), request.headers()));

        Response response = chain.proceed(request);

        long t2 = System.nanoTime();//收到響應的時間

        //這里不能直接使用response.body().string()的方式輸出日志
        //因為response.body().string()之后,response中的流會被關閉,程序會報錯,我們需要創建出一
        //個新的response給應用層處理
        ResponseBody responseBody = response.peekBody(1024 * 1024);

        System.out.println(String.format("接收響應: [%s] %n返回json:【%s】 %.1fms%n%s",
                response.request().url(),
                responseBody.string(),
                (t2 - t1) / 1e6d,
                response.headers()));
        return response;
    }
}

2、

 

發送請求

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM