1. 简介
我们在《OkHttp 使用指南》一文中已经介绍了 OkHttp 客户端的基础用法。
本文则聚焦于 OkHttp 3.x 版本中,如何发送各种类型的 POST 请求。内容虽短,但覆盖了日常开发中最常见的几种场景,帮你少踩坑、提升效率。
2. 基础 POST 请求
✅ 最常见的表单提交场景,比如登录、注册等,使用 FormBody.Builder
构建请求体即可。
它会自动将参数编码为 application/x-www-form-urlencoded
格式,简单粗暴又实用。
@Test
public void whenSendPostRequest_thenCorrect()
throws IOException {
RequestBody formBody = new FormBody.Builder()
.add("username", "test")
.add("password", "test")
.build();
Request request = new Request.Builder()
.url("https://api.example.com/users")
.post(formBody)
.build();
Call call = client.newCall(request);
Response response = call.execute();
assertThat(response.code(), equalTo(200));
}
⚠️ 注意:.post(formBody)
必须显式调用,否则默认是 GET。
3. 带认证的 POST 请求
❌ 很多人手动拼 Authorization
头,容易出错。推荐使用 OkHttp 自带的 Credentials.basic()
工具方法,自动完成 Base64 编码。
适用于 Basic Auth 场景(虽然现在用得少了,但对接老系统时还是常遇到)。
@Test
public void whenSendPostRequestWithAuthorization_thenCorrect()
throws IOException {
String postBody = "test post";
Request request = new Request.Builder()
.url("https://api.example.com/secure-endpoint")
.addHeader("Authorization", Credentials.basic("admin", "secret123"))
.post(RequestBody.create(
MediaType.parse("text/x-markdown"), postBody))
.build();
Call call = client.newCall(request);
Response response = call.execute();
assertThat(response.code(), equalTo(200));
}
📌 小贴士:MediaType.parse()
参数记得检查引号闭合,上面代码原示例有语法错误(少了一个引号),已修复。
4. 发送 JSON 数据
✅ 当前主流的接口通信格式,必须设置 Content-Type: application/json
。
通过 RequestBody.create()
指定媒体类型即可。
@Test
public void whenPostJson_thenCorrect() throws IOException {
String json = "{\"id\":1,\"name\":\"John\"}";
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), json);
Request request = new Request.Builder()
.url("https://api.example.com/users/detail")
.post(body)
.build();
Call call = client.newCall(request);
Response response = call.execute();
assertThat(response.code(), equalTo(200));
}
💡 建议:实际项目中通常配合 Jackson/Gson 将对象序列化为 JSON 字符串后再发送,避免手拼字符串出错。
5. 多部分请求(Multipart POST)
✅ 文件上传 + 表单字段混合提交的标准做法。
使用 MultipartBody.Builder
,并设置 .setType(MultipartBody.FORM)
,这是关键!
@Test
public void whenSendMultipartRequest_thenCorrect()
throws IOException {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("username", "test")
.addFormDataPart("password", "test")
.addFormDataPart("file", "file.txt",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("src/test/resources/test.txt")))
.build();
Request request = new Request.Builder()
.url("https://api.example.com/users/multipart")
.post(requestBody)
.build();
Call call = client.newCall(request);
Response response = call.execute();
assertThat(response.code(), equalTo(200));
}
📌 注意事项:
addFormDataPart
用于添加普通字段或文件- 文件部分需用
RequestBody.create
指定文件内容和 MIME 类型 - 常见类型如
image/jpeg
,application/pdf
等可根据文件扩展名动态设置
6. 自定义字符编码
OkHttp 默认使用 UTF-8 编码,大多数情况下没问题。
但如果你对接的是某些老旧系统,可能要求使用 UTF-16 或其他编码,这时就需要手动指定。
6.1 默认编码验证
@Test
public void whenPostJsonWithoutCharset_thenCharsetIsUtf8() throws IOException {
final String json = "{\"id\":1,\"name\":\"John\"}";
final RequestBody body = RequestBody.create(
MediaType.parse("application/json"), json);
String charset = body.contentType().charset().displayName();
assertThat(charset, equalTo("UTF-8"));
}
6.2 指定 UTF-16 编码
@Test
public void whenPostJsonWithUtf16Charset_thenCharsetIsUtf16() throws IOException {
final String json = "{\"id\":1,\"name\":\"John\"}";
final RequestBody body = RequestBody.create(
MediaType.parse("application/json; charset=utf-16"), json);
String charset = body.contentType().charset().displayName();
assertThat(charset, equalTo("UTF-16"));
}
⚠️ 踩坑提醒:服务端必须支持该编码格式,否则会解析失败。建议优先使用 UTF-8,除非有特殊需求。
7. 总结
本文涵盖了 OkHttp 发送 POST 请求的五种典型场景:
- ✅ 普通表单提交
- ✅ 带 Basic Auth 的请求
- ✅ JSON 数据传输
- ✅ 文件上传(Multipart)
- ✅ 自定义字符编码处理
这些例子覆盖了绝大多数实际开发中的需求。建议集合备用,避免每次都要查文档。
示例代码已整理至 GitHub:https://github.com/yourname/tutorials/tree/master/libraries-http