OkHttp 使用指南:常见场景与代码示例
OkHttp 是一个强大的 HTTP 客户端库,广泛应用于 Java 和 Kotlin 项目中。本文将介绍 OkHttp 在各种常见场景下的使用方法,帮助开发者快速掌握其核心功能。
同步 GET 请求
同步请求是最基础的 HTTP 操作,会阻塞当前线程直到获得响应结果。适合在后台线程中使用。
val client = OkHttpClient()
val request = Request.Builder()
.url("https://example.com/data.txt")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("请求失败: $response")
// 打印响应头
response.headers.forEach { name, value ->
println("$name: $value")
}
// 获取响应体内容
println(response.body?.string())
}
注意事项:
string()
方法适合小文件(<1MB),大文件应使用流式处理- 务必使用
use
或 try-with-resources 确保资源释放
异步 GET 请求
异步请求不会阻塞调用线程,通过回调处理响应结果,适合主线程使用。
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://example.com/data.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody body = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("请求失败: " + response);
}
// 处理响应
System.out.println(body.string());
}
}
});
请求头操作
OkHttp 提供了灵活的请求头管理方式:
val request = Request.Builder()
.url("https://api.example.com/data")
.header("User-Agent", "MyApp") // 设置单一值,会覆盖同名header
.addHeader("Accept", "text/plain") // 添加值,允许多个同名header
.addHeader("Accept", "application/json")
.build()
读取响应头时:
response.header("Name")
获取最后一个值response.headers("Name")
获取所有值列表
POST 请求示例
发送字符串
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String json = "{\"name\":\"value\"}";
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url("https://api.example.com/post")
.post(body)
.build();
发送表单数据
val formBody = FormBody.Builder()
.add("username", "user123")
.add("password", "secret")
.build()
val request = Request.Builder()
.url("https://example.com/login")
.post(formBody)
.build()
发送文件
File file = new File("document.pdf");
MediaType contentType = MediaType.parse("application/pdf");
Request request = new Request.Builder()
.url("https://example.com/upload")
.post(RequestBody.create(contentType, file))
.build();
流式上传
对于大文件或动态生成的内容,可以使用流式上传:
val requestBody = object : RequestBody() {
override fun contentType() = "text/plain".toMediaType()
override fun writeTo(sink: BufferedSink) {
// 动态写入内容
sink.writeUtf8("第一行\n")
sink.writeUtf8("第二行\n")
}
}
val request = Request.Builder()
.url("https://example.com/stream")
.post(requestBody)
.build()
多部分表单上传
上传文件和其他字段:
RequestBody fileBody = RequestBody.create(
MediaType.parse("image/jpeg"),
new File("photo.jpg"));
RequestBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "Vacation Photo")
.addFormDataPart("image", "photo.jpg", fileBody)
.build();
Request request = new Request.Builder()
.url("https://example.com/upload")
.post(multipartBody)
.build();
最佳实践
- 客户端复用:OkHttpClient 应该被复用,而不是为每个请求创建新实例
- 响应体关闭:确保总是关闭 Response 和 ResponseBody 对象
- 大文件处理:超过 1MB 的文件应使用流式处理而非全部加载到内存
- 超时设置:根据需求配置合理的连接、读取和写入超时
- 错误处理:检查 response.isSuccessful 并处理非 2xx 响应
通过掌握这些常见场景的使用方法,开发者可以充分利用 OkHttp 的强大功能,构建高效可靠的网络请求处理逻辑。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考