首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

OkHttp 核心用法詳解:同步/異步請求、Header 處理與最佳實踐

     編輯:Java 相關知識

Header 處理機制

OkHttp 將 HTTP Header 視為 Map<String, List<String>>,提供鏈式 API:

  • header(name, value):設置單值(重複調用覆蓋)
  • addHeader(name, value):追加多值(如多個 Set-Cookie)
  • header(name):讀取最後一個值
  • headers(name):讀取所有值列表
Request request = new Request.Builder()
    .url("https://www.baidu.com")
    .header("User-Agent", "MyApp/1.0")           // 設置單值
    .addHeader("Accept", "application/json")     // 追加值
    .addHeader("Accept", "text/html")            // 同名多值
    .build();

Response response = client.newCall(request).execute();
System.out.println("Server: " + response.header("Server"));      // 單值
System.out.println("Set-Cookie: " + response.headers("Set-Cookie")); // 列表

同步 GET 請求

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
    .url("https://publicobject.com/helloworld.txt")
    .build();

try (Response response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) throw new IOException("HTTP " + response.code());
    
    // 打印 Header
    Headers headers = response.headers();
    for (int i = 0; i < headers.size(); i++) {
        System.out.println(headers.name(i) + ": " + headers.value(i));
    }
    
    // 小文件直接讀字符串
    System.out.println(response.body().string());
    
    // 大文件必須用流處理!
    // try (InputStream is = response.body().byteStream()) { ... }
}

異步 GET 請求

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        e.printStackTrace(); // 網絡異常、DNS 失敗等
    }
    
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (!response.isSuccessful()) {
            throw new IOException("HTTP " + response.code());
        }
        // 注意:回調運行在工作線程,UI 更新需切主線程
        System.out.println(response.body().string());
    }
});
// 主線程繼續執行,不阻塞

核心最佳實踐

  1. 單例 Client:OkHttpClient 線程安全、支持連接池,全局共享一個實例
  2. 超時配置:
    new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.SECONDS)
        .build();
    
  3. 大文件流式處理:禁止 response.body().string(),必須用 byteStream() 或 charStream()
  4. 攔截器:添加日誌、簽名、重試、緩存等橫切邏輯
    .addInterceptor(chain -> {
        Request req = chain.request().newBuilder()
            .addHeader("Authorization", "Bearer " + token)
            .build();
        return chain.proceed(req);
    })
    
  5. 取消請求:call.cancel() 可取消進行中的請求

常見坑點

問題原因解決
異步回調中更新 UI 崩潰回調在工作線程Android: runOnUiThread / Handler / LiveData
大文件 OOMstring() 全量加載內存使用 byteStream() 分塊讀取
重定向循環服務端誤配置設置 .followRedirects(false) 或攔截器檢測
證書驗證失敗自簽名/過期證書配置自定義 SSLSocketFactory(僅測試環境)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved