简体   繁体   中英

How can I parse a json representation of a response?

I'm pretty new to JAVA so my apologies for asking a rather elementary question.

I have a json string that looks like this.

{"statusCode":201,
 "body":"[[\"food_corn\",\"48\"],[\"food_potatoes\",\"130\"],[\"food_rice\",\"80\"]]",
 "headers":{"Access-Control-Allow-Origin":"*"}}

I'm only interested in the body of the text which may have any number of elements.

At the end I'd like to have a map with the item name as the key and the number as the correspond value (as an integer).

Thanks for the help!


Update on where I'm at

String decoded = new String(invoke.getPayload().array(), "UTF-8");
HashMap<String, Object> map = new ObjectMapper().readValue(decoded, HashMap.class);
Object body = map.get("body")

where body looks like this

[["food_corn","48"],["food_potatoes","130"],["food_rice","80"],["food_wheat","999"]]

So then I try parsing it into an array like so

JSONArray array = new JSONArray(body);

But I get the error

EXCEPTION: JSONArray initial value should be a string or collection or array.

Which doesn't make sensee to me because the above looks like an array of arrays, no?

 @SneakyThrows
 @Test
 public void covertTest() {
  String str = "{\"statusCode\":201,\"body\":\"[[\\\"food_corn\\\",\\\"48\\\"],[\\\"food_potatoes\\\",\\\"130\\\"],"
    + "[\\\"food_rice\\\",\\\"80\\\"]]\",\"headers\":{\"Access-Control-Allow-Origin\":\"*\"}}";
  Map map = objectMapper.readValue(str, Map.class);
  System.out.println(map);
//{statusCode=201, body=[["food_corn","48"],["food_potatoes","130"],["food_rice","80"]], headers={Access-Control-Allow-Origin=*}}
}

Parsing json to obj is called deserialization. You need to use some libarary to do this. I recommend Jackson. https://github.com/FasterXML/jackson

The below code is a sample to deserialize json into an object of a class. You need to define a class with all the fields then it will create an object of that class mapping to the json data.

    public void deserializeData() {
      var mapper = new ObjectMapper();
      var json = "{\"statusCode\":201,
     "body":"[[\"food_corn\",\"48\"],[\"food_potatoes\",\"130\"],[\"food_rice\",\"80\"]]",
     "headers":{"Access-Control-Allow-Origin":"*"}}";
      var throwable = catchThrowable(() -> mapper.readValue(json, JSONBody.class));
      log.info("You need to use an empty constructor: {}", throwable.getMessage());
      assertThat(throwable).isInstanceOf(InvalidDefinitionException.class);
    }

Got it to work. Here's how I did it in case it helps anyone in the future.

(The invoke variable is the response from invoking a lambda call form a lambda call within the same region.)

try {
     String decoded = new String(invoke.getPayload().array(), "UTF-8");
     HashMap<String, Object> map = new ObjectMapper().readValue(decoded, HashMap.class);
     String body = map.get("body").toString();
     JSONArray array = new JSONArray(body);

     Map<String, Integer> inventory = new HashMap<>();
     for (Integer i=0; i < array.length(); i++) {
         JSONArray tuple = array.getJSONArray(i);
         String itemName = tuple.getString(0);
         Integer itemCount = tuple.getInt(1);
         inventory.put(itemName, itemCount);
     }
     logger.log("COMPILED INVENTORY: "+inventory.toString()+"\n");
} catch (Exception e) {
     logger.log("EXCEPTION: "+e.getMessage()+"\n");
}

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