android - 如何从 JSONObject 中删除 nameValuePairs 键?

我正在开发一个 Android 项目,该项目需要一个 JSONObject 作为我的 POST 请求的正文。 放置 JSON 的键和值后,我得到以下行:

{
    "xxxx":"zzzzzzz",
    "yyyy":"uuuuuuu"
}

但是服务器得到了以下信息:

{
    "name_value_pairs": {
                        "xxxx":"zzzzzzz",
                        "yyyy":"uuuuuuu"
    }
}

我已经尝试过 JSONStringer,但它并没有真正的帮助,因为请求的 Content-Typeapplication/json

更新

我没有尝试构造 JSONObject,因为它已经通过使用以下代码行完成(@osayilgan 给出的相同):

JSONObject jsonRequest = new JSONObject();
jsonRequest.put("xxxx", "zzzzzzz");
jsonRequest.put("yyyy", "uuuuuuu");

这不是问题所在。下面描述的接口(interface)用于与服务器通信。

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void testFunction(@Body JSONObject jsonObject, Callback<Response> callback);
}

服务器收到了第二个 JSON 作为正文的请求,这令人失望。我注意到键 name_value_pairs 会自动添加到对象中。

有人知道我该如何解决这个问题吗?

最佳答案

问题:

Retrofit 默认使用 GSON 将 HTTP 正文与 JSON 进行转换。 @Body 注解指定的对象将被传递给 GSON 进行序列化,这基本上将 JAVA 对象转换为 JSON 表示。此 JSON 表示将是 HTTP 请求正文。

JSONObject 将所有键值映射存储在一个名为 nameValuePairs 的成员变量中。 下面是 JSONObject 实现的摘录:

public class JSONObject {
    ...
    private final Map<String, Object> nameValuePairs;
    ...
}

当您将 JSONObject 传递给 @Body 注释时,此 JSONObject 会被序列化,因此 HTTP 请求正文包含:{"nameValuePairs": "actual JSON Object"}。

解决方案:

将实际的 JAVA 对象传递给 @Body 注释,而不是对应的 JSONObject。 GSON 将负责将其转换为 JSON 表示形式。

例如

class HTTPRequestBody {
   String key1 = "value1";
   String key2 = "value2";
   ...
}

// GSON will serialize it as {"key1": "value1", "key2": "value2"}, 
// which will be become HTTP request body.

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void postJson(@Body HTTPRequestBody body, Callback<Response> callback);
}

// Usage
MyService myService = restAdapter.create(MyService.class);
myService.postJson(new HTTPRequestBody(), callback);

替代解决方案:

如果您仍想将原始 JSON 作为 HTTP 请求正文发送,请按照改造作者 here 中提到的解决方案进行操作。 .

建议的解决方案之一是使用 TypedInput :

public interface MyService {
  @POST("/test")
  void postRawJson(@Body TypedInput body, Callback<Response> callback);
}

String json = jsonRequest.toString();
TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8"));
myService.postRawJson(in, callback);

https://stackoverflow.com/questions/26022133/

相关文章:

json - HATEOAS中 "_embedded"的含义及用法

javascript - 如何使用 Angular-Translate 显示翻译?

json - Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY 无

android - 对等通信选项

mysql - 如何在 MySQL 中编写可以解析列中 JSON 数据的查询?

python - 如何在scrapy中实现嵌套项?

c# - 类型是接口(interface)或抽象类,不能实例化

bash - jq 直接替换文件上的文本(如 sed -i)

json - meteor `Deps.autorun` 与 `Collection.observ

json - 遍历 JSON 文件 PowerShell