简体   繁体   中英

How do I remove backslashes before quotes from a JSONObject string?

Background

I have a list of strings (records) that are dynamically created by a class. Each record may have different keys (eg favorite_pizza on first, favorite_candy on second).

// 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\"}");

The list of records is then passed to a separate HTTP request class.

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

Inside the HTTP request service, I want to build a JSON request body:

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

I'm using org.json.JSONObject to add the records key and create the request body:

JSONObject body = new JSONObject();

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

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

Issues

When I run my junit test in IntelliJ, the request body contains a backslash before each quote:

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\"}"]}"

And when I make the request it fails because the body is not formatted correctly:

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

Questions

  • Why is JSONObject including the backslashes before each quote?
  • How do I remove the backslashes?

You are creating a list of string, which is not what you want.

You should instead create a list of objects (Maps)

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);

This is a quite common mistake (it seems), to try to serialize strings formatted like json objects expecting is the same thing as passing a the object itself.

UPDATE:

Or if you have a json serialized object list then ...

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());

If your record strings are already valid json you can either

  1. Iterate over them, converting them one at a time into a JSONObject (see here ) and then add the result to a JSONArray which you can manipulate if needed.

  2. Create the array entirely by hand since it's just comma separated record strings inside square brackets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM