You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Retrofit的POST请求中将JSONObject作为@Body参数使用

问题根因

你使用的Retrofit配置了GsonConverterFactory作为请求体转换器,Gson在序列化org.json.JSONObject类型的对象时,不会将它识别为特殊的JSON结构,而是按照普通Java对象的序列化规则,把它内部所有public的成员变量、静态常量全部序列化输出。你看到的nameValuePairs是JSONObject内部存储键值对的成员变量,NEGATIVE_ZERO是JSONObject内置的静态常量,所以才会出现在最终的请求体中。

解决方案

方案1:使用Gson的JsonObject类替代org.json.JSONObject

这是适配成本最低的方案,把你构造动态JSON的逻辑从org.json.JSONObject改成Gson库自带的com.google.gson.JsonObject,接口参数直接定义为@Body JsonObject jsonObject即可,Gson序列化自身的JsonObject类时会直接输出正确的JSON结构,不会生成多余字段。
示例代码:

// 构造动态JSON
JsonObject jsonObject = new JsonObject();
JsonObject cfField = new JsonObject();
cfField.addProperty("pdf-name", "CAPTAIN BOBOYz");
cfField.addProperty("pdf-email", "boy@test.com");
// 剩余字段依次添加
jsonObject.add("cf-field", cfField);
jsonObject.addProperty("lead_id", "273993");

// 直接传入接口调用即可
api.updateLead(token, jsonObject).enqueue(/* 你的回调逻辑 */);

方案2:将org.json.JSONObject转成字符串后用RequestBody传递

如果你不想修改现有构造org.json.JSONObject的逻辑,可以把构造好的JSONObject转成原始JSON字符串,再封装为RequestBody传入接口,直接跳过Gson对JSONObject的序列化流程:

  1. 修改Retrofit接口定义:
@Headers(PARAM_HEADER_JSON)
@POST(HttpConstants.LEAD_EDIT)
Call<LeadDetailsResult> updateLead(@Header(PARAM_TOKEN) String token, @Body RequestBody body);
  1. 调用接口前做如下转换:
// 你原来构造好的org.json.JSONObject对象
JSONObject yourJson = ...;
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), yourJson.toString());
// 传入body调用接口即可
api.updateLead(token, body).enqueue(/* 你的回调逻辑 */);

方案3:自定义Gson TypeAdapter适配org.json.JSONObject

如果项目里大量使用org.json.JSONObject作为请求体,不想逐个修改调用逻辑,可以给Gson添加自定义的TypeAdapter,专门处理org.json.JSONObject的序列化逻辑:

public class JSONObjectTypeAdapter extends TypeAdapter<JSONObject> {
    @Override
    public void write(JsonWriter out, JSONObject value) throws IOException {
        if (value == null) {
            out.nullValue();
            return;
        }
        out.jsonValue(value.toString());
    }

    @Override
    public JSONObject read(JsonReader in) throws IOException {
        try {
            return new JSONObject(JsonParser.parseReader(in).getAsString());
        } catch (JSONException e) {
            throw new IOException(e);
        }
    }
}

然后在构造Gson实例时注册这个适配器,再把自定义的Gson实例传给GsonConverterFactory构造你的Retrofit实例即可,原有代码不需要做任何修改就能正常输出正确的JSON结构。

内容的提问来源于stack exchange,提问作者nerdy kid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:48:00