OkHttp用法-Java调用http服务

特点:高性能,支持异步请求,连接池优化

官方文档:提供快速入门指南和高级功能(如拦截器、连接池)的详细说明,GitHub仓库包含丰富示例。

社区资源:中文教程丰富,GitHub高星标(40k+),社区活跃度高,问题响应快。

维护状态:由Square公司持续维护,更新频繁,支持最新TLS和HTTP/2特性。

java 复制代码
// 1. 添加 Maven 依赖
// <dependency>
//     <groupId>com.squareup.okhttp3</groupId>
//     <artifactId>okhttp</artifactId>
//     <version>4.9.3</version>
// </dependency>

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class OkHttpExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://api.example.com/data")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String result = response.body().string();
                System.out.println("Response: " + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

OkHttp 核心用法详解(从基础到实战)

一、基础用法
1. 创建 OkHttpClient 实例
java 复制代码
// 基础配置(可扩展代理、超时等)
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS) // 连接超时
    .readTimeout(30, TimeUnit.SECONDS)    // 读取超时
    .writeTimeout(30, TimeUnit.SECONDS)   // 写入超时
    .retryOnConnectionFailure(true)      // 连接失败自动重试
    .build();
2. 构建请求(GET 示例)
java 复制代码
Request request = new Request.Builder()
    .url("https://api.example.com/data")
    .header("User-Agent", "OkHttp Example") // 添加请求头
    .get() // 默认是GET,可省略
    .build();
3. 发送请求
  • 同步请求(阻塞当前线程):

    java 复制代码
    try (Response response = client.newCall(request).execute()) {
        if (response.isSuccessful()) {
            String result = response.body().string();
            System.out.println("Response: " + result);
        } else {
            System.out.println("Error: " + response.code());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
  • 异步请求(非阻塞,通过回调处理):

    java 复制代码
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                String result = response.body().string();
                System.out.println("Async Response: " + result);
            }
        }
    
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
    });
二、POST 请求与数据提交
1. 提交 JSON 数据
java 复制代码
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

String jsonBody = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
RequestBody body = RequestBody.create(jsonBody, JSON);

Request request = new Request.Builder()
    .url("https://api.example.com/post")
    .post(body)
    .build();
2. 提交表单数据
java 复制代码
RequestBody formBody = new FormBody.Builder()
    .add("username", "user")
    .add("password", "pass")
    .build();

Request request = new Request.Builder()
    .url("https://api.example.com/login")
    .post(formBody)
    .build();
三、文件上传与下载
1. 文件上传(Multipart)
java 复制代码
File file = new File("path/to/file.jpg");
RequestBody fileBody = RequestBody.create(file, MediaType.parse("image/jpeg"));

RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", file.getName(), fileBody)
    .addFormDataPart("description", "Test upload")
    .build();

Request request = new Request.Builder()
    .url("https://api.example.com/upload")
    .post(requestBody)
    .build();
2. 文件下载
java 复制代码
Request request = new Request.Builder()
    .url("https://api.example.com/file.zip")
    .build();

try (Response response = client.newCall(request).execute()) {
    if (response.isSuccessful()) {
        byte[] fileData = response.body().bytes();
        Files.write(Paths.get("downloaded.zip"), fileData);
    }
}
四、高级功能
1. 拦截器(Logging & Header 修改)
java 复制代码
// 日志拦截器
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);

// 自定义 Header 拦截器
Interceptor headerInterceptor = chain -> {
    Request originalRequest = chain.request();
    Request newRequest = originalRequest.newBuilder()
        .header("Authorization", "Bearer token123")
        .build();
    return chain.proceed(newRequest);
};

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(logging)
    .addInterceptor(headerInterceptor)
    .build();
2. 连接池配置(优化性能)
java 复制代码
ConnectionPool pool = new ConnectionPool(5, 5, TimeUnit.MINUTES); // 最大空闲连接5,保持5分钟
OkHttpClient client = new OkHttpClient.Builder()
    .connectionPool(pool)
    .build();
五、最佳实践
  1. 复用 OkHttpClient 实例:避免频繁创建/销毁,减少资源开销。
  2. 异步请求优先:在 Android 等 UI 线程受限环境中,必须使用异步请求。
  3. 合理配置超时 :根据业务场景调整 connectTimeoutreadTimeout
  4. 使用拦截器统一处理:日志、错误重试、Header 添加等逻辑集中管理。
  5. 大文件下载用流式处理 :避免 response.body().string() 导致内存溢出,改用 response.body().byteStream() 逐块读取。
六、常见问题
  • Q:如何取消正在进行的请求?

    A:调用 Call.cancel(),需在回调中检查 isCanceled()

  • Q:如何处理 HTTPS 证书问题?

    A:通过 CertificatePinner 配置证书固定,或自定义 X509TrustManager(需谨慎)。

  • Q:OkHttp 与 Retrofit 的关系?

    A:Retrofit 是基于 OkHttp 的 RESTful 客户端封装,提供更简洁的 API 调用方式。


通过以上内容,您已掌握 OkHttp 的核心用法,可根据项目需求灵活选择同步/异步请求、配置拦截器、优化连接池,实现高效稳定的网络通信。

相关推荐
爱尚你19939 分钟前
Java 泛型与类型擦除:为什么解析对象时能保留泛型信息?
java
电商数据girl32 分钟前
酒店旅游类数据采集API接口之携程数据获取地方美食品列表 获取地方美餐馆列表 景点评论
java·大数据·开发语言·python·json·旅游
CircleMouse32 分钟前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
ktkiko1139 分钟前
顶层架构 - 消息集群推送方案
java·开发语言·架构
zybsjn44 分钟前
后端系统做国际化改造,生成多语言包
java·python·c#
Unity官方开发者社区1 小时前
《Cryptical Path》开发诀窍:像玩游戏一样开发一款类Rogue游戏
java·游戏·玩游戏
_星辰大海乀1 小时前
表的设计、聚合函数
java·数据结构·数据库·sql·mysql·数据库开发
IT成长史2 小时前
deepseek梳理java高级开发工程师微服务面试题-进阶版
java·spring cloud·微服务
zkmall2 小时前
Java + 鸿蒙双引擎:ZKmall开源商城如何定义下一代B2C商城技术标准?
java·开源·harmonyos
陌路物是人非2 小时前
uniapp取消浏览自动填充
java·服务器·uni-app