如何修改OkHttp3中MultipartBody分片的请求头?
解决OkHttp3 MultipartBody自动添加charset和Content-Length的问题
不用手动编辑负载字符串,通过OkHttp的API完全可以实现自定义Multipart part的头部,避免自动添加你不需要的charset=utf-8和Content-Length。核心思路是自定义RequestBody,接管内容类型和写入逻辑,绕过OkHttp的默认行为。
具体实现步骤
- 定义不带字符编码的MediaType
- 创建自定义RequestBody,重写关键方法控制头部和内容写入
// 定义不带charset的JSON MediaType MediaType JSON_PLAIN = MediaType.get("application/json"); // 自定义RequestBody,控制头部和写入行为 RequestBody customJsonBody = new RequestBody() { @Override public MediaType contentType() { // 返回不带charset的MediaType,避免自动添加charset=utf-8 return JSON_PLAIN; } @Override public void writeTo(BufferedSink sink) throws IOException { // 直接写入JSON内容,确保格式正确 sink.writeUtf8("{\"foo\": true, \"bar\": \"some string\"}"); } @Override public long contentLength() { // 返回-1,告诉OkHttp不要自动计算并添加Content-Length头 return -1; } }; // 构建MultipartBody时使用这个自定义RequestBody RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.MIXED) .addPart(customJsonBody) .build(); // 验证生成的内容(和你示例中的验证代码一致) Buffer buffer = new Buffer(); requestBody.writeTo(buffer); String requestBodyAsString = buffer.readUtf8(); System.out.println(requestBodyAsString);
为什么这个方法有效?
- contentType():返回不带
charset后缀的MediaType,OkHttp就不会自动在Content-Type头里追加; charset=utf-8。 - contentLength():返回-1时,OkHttp会跳过自动计算Content-Length的逻辑,也就不会给Multipart part添加这个头。
- writeTo():直接写入JSON字符串,保证内容和你预期的完全一致,没有额外的处理。
生成的最终内容
执行上述代码后,生成的Multipart负载会符合服务器的要求:
--8d863b3b-72a0-4b29-b4f4-5cc0b68d8117 Content-Type: application/json {"foo": true, "bar": "some string"} --8d863b3b-72a0-4b29-b4f4-5cc0b68d8117--
内容的提问来源于stack exchange,提问作者ZeitPolizei
相关产品推荐
相关产品推荐

