背景

我有一个由类动态创建的字符串(记录)列表。每个记录可能具有不同的键(例如,第一个键为favorite_pizza,第二个键为favorite_candy)。

// Note: These records are dynamically created and not stored
// in this way. This is simply for display purposes.
List<String> records =
    Arrays.asList(
        "{\"name\":\"Bob\",\"age\":40,\"favorite_pizza\":\"Cheese\"}",
        "{\"name\":\"Jill\",\"age\":22,\"favorite_candy\":\"Swedish Fish\"}");


记录列表然后传递到一个单独的HTTP请求类。

public Response addRecords(List<String> records) {
    ...
}


在HTTP请求服务内部,我想构建一个JSON请求主体:

{
  "records": [
    {
      "name": "Bob",
      "age": 40,
      "favorite_pizza": "Cheese"
    },
    {
      "name": "Jill",
      "age": 22,
      "favorite_candy": "Swedish Fish"
    }
  ]
}


我正在使用org.json.JSONObject添加records密钥并创建请求正文:

JSONObject body = new JSONObject();

// Add the "records" key
body.put("records", records);

// Create the request body
body.toString();


问题

当我在IntelliJ中运行junit测试时,请求主体在每个引号之前都包含一个反斜杠:

org.junit.ComparisonFailure:
Expected :"{"records":["{"name":"Bob","age":40,"favorite_pizza":"Cheese"}","{"name":"Jill","age":22,"favorite_candy":"Swedish Fish"}"]}"
Actual   :"{"records":["{\"name\":\"Bob\",\"age\":40,\"favorite_pizza\":\"Cheese\"}","{\"name\":\"Jill\",\"age\":22,\"favorite_candy\":\"Swedish Fish\"}"]}"


当我发出请求时,它失败了,因为主体的格式不正确:

{
  "records": [
    "{\"name\":\"Bob\",\"age\":40,\"favorite_pizza\":\"Cheese\"}",
    "{\"name\":\"Jill\",\"age\":22,\"favorite_candy\":\"Swedish Fish\"}"
  ]
}


问题


为什么JSONObject在每个引号前都包含反斜杠?
如何删除反斜杠?

最佳答案

您正在创建一个字符串列表,这不是您想要的。

您应该改为创建对象列表(地图)

    Map<String, Object> m1 = new LinkedHashMap<>();
    m1.put("name", "Bob");
    m1.put("age", 40);
    m1.put("favorite_pizza", "Cheese");

    LinkedHashMap<String, Object> m2 = new LinkedHashMap<>();
    m2.put("name", "Jill");
    m2.put("age", 22);
    m2.put("favorite_candy", "Swedish Fish");
    List<LinkedHashMap<String, Object>> records = Arrays.asList(m1,m2);

    JSONObject body = new JSONObject();

    // Add the "records" key
    body.put("records", records);


这是一个很常见的错误(看来),尝试序列化格式化为json对象期望的字符串与传递对象本身是同一回事。

更新:

或者,如果您有json序列化的对象列表,则...

    List<String> recordSource =
        Arrays.asList(
            "{\"name\":\"Bob\",\"age\":40,\"favorite_pizza\":\"Cheese\"}",
            "{\"name\":\"Jill\",\"age\":22,\"favorite_candy\":\"Swedish Fish\"}");
    List<JSONObject> records =
        recordSource.stream().map(JSONObject::new).collect(Collectors.toList());

    JSONObject body = new JSONObject();

    // Add the "records" key
    body.put("records", records);
    System.out.println(body.toString());

07-24 09:37
查看更多