OkHttp 入门:Java 网络请求其实很简单
OkHttp 是 Square 开源的一款 HTTP 客户端,主要用于 Java、Kotlin 和 Android 中发送网络请求。(Square )
简单来说,我们平时写:
客户端 → HTTP 请求 → 服务端 → HTTP 响应
OkHttp 就是帮我们完成中间这一套 HTTP 通信。
目前 OkHttp 5 已经是稳定版本,本文使用 5.5.0 作为示例。(GitHub )
1. 引入 OkHttp
Gradle 项目加入:
dependencies {
implementation("com.squareup.okhttp3:okhttp:5.5.0")
}
然后创建客户端:
OkHttpClient client = new OkHttpClient();
OkHttpClient 可以理解成整个 OkHttp 的核心入口。
通常一个项目中复用一个 OkHttpClient 即可。
2. 发送 GET 请求
比如请求一个接口:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://httpbin.org/get")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.body() != null) {
System.out.println(response.body().string());
}
}
这里实际上只干了三件事:
创建 OkHttpClient
↓
创建 Request
↓
执行 Call
↓
获得 Response
其中:
client.newCall(request)
会创建一个 HTTP 请求任务。
而:
execute()
负责真正执行请求。
3. 异步请求
execute() 是同步请求。
也就是说:
发送请求
↓
等待服务器
↓
服务器返回
↓
程序继续执行
如果不想阻塞当前线程,可以使用:
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("请求失败");
}
@Override
public void onResponse(Call call, Response response)
throws IOException {
if (response.body() != null) {
System.out.println(response.body().string());
}
}
});
这时候请求会异步执行。
成功:
onResponse()
失败:
onFailure()
Android 开发中通常更加常见这种方式。
4. POST 请求
比如发送 JSON:
String json = """
{
"username": "admin",
"password": "123456"
}
""";
MediaType JSON =
MediaType.get("application/json; charset=utf-8");
RequestBody body =
RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url("https://example.com/login")
.post(body)
.build();
Response response =
client.newCall(request).execute();
核心区别就是多了一个:
RequestBody
可以简单理解为:
GET
Request
↓
Server
而 POST 通常是:
Request
│
└── RequestBody
↓
Server
RequestBody 就是我们发送给服务器的数据。
5. 添加请求头
很多接口还需要 Token。
例如:
Request request = new Request.Builder()
.url("https://example.com/user")
.addHeader(
"Authorization",
"Bearer xxxxx"
)
.build();
最终 HTTP 请求大概就是:
GET /user HTTP/1.1
Host: example.com
Authorization: Bearer xxxxx
所以 OkHttp 本质上只是帮我们更加方便地构造 HTTP 请求。
6. OkHttp 是怎么实现请求的?
初学阶段可以把 OkHttp 的工作流程理解成:
Request
↓
OkHttpClient
↓
Call
↓
Interceptor
↓
寻找 / 建立连接
↓
发送 HTTP 请求
↓
服务器
↓
Response
这里面有几个比较重要的东西。
OkHttpClient
负责整个客户端配置,例如:
超时时间
连接池
拦截器
代理
缓存
DNS
Request
描述:
请求哪个 URL
使用 GET 还是 POST
Header 是什么
Body 是什么
Call
代表一次 HTTP 请求任务。
因此:
client.newCall(request)
可以理解为:
把 Request 包装成一个真正可以执行的网络任务。
Response
服务器响应之后,OkHttp 会把结果封装成:
Response
我们可以从里面取得:
response.code();
response.headers();
response.body();
7. Interceptor 拦截器
OkHttp 还有一个非常重要的功能:
Interceptor
例如给所有请求统一添加 Token:
OkHttpClient client =
new OkHttpClient.Builder()
.addInterceptor(chain -> {
Request request =
chain.request()
.newBuilder()
.addHeader(
"Authorization",
"Bearer xxxxx"
)
.build();
return chain.proceed(request);
})
.build();
这样以后发送:
请求 A
请求 B
请求 C
都会经过这个拦截器。
因此可以统一处理:
Token
日志
Header
错误处理
接口耗时
8. 最后理解一下 OkHttp
OkHttp 并没有什么神秘的。
最核心的模型其实只有:
OkHttpClient
↓
Request
↓
Call
↓
HTTP 网络通信
↓
Response
再往里面深入,则会涉及:
Interceptor
Dispatcher
ConnectionPool
DNS
Socket
HTTP/1.1
HTTP/2
TLS
所以学习 OkHttp 比较推荐的路线是:
GET / POST
↓
Request / Response
↓
同步 / 异步
↓
Interceptor
↓
连接池
↓
OkHttp 请求源码流程
掌握前四个,基本就已经可以在实际项目中使用 OkHttp 了。