Home > database >  Java HashMap one of the <V> has a <K,V> and need to fetch the value by the key
Java HashMap one of the <V> has a <K,V> and need to fetch the value by the key

Time:12-23

I have an API response that gives the below result . The response Map has 3 <K,V>. and One of the content has another <K,V> in its value . My problem here is I need to fetch the value of "plan_id" which is a Key . this simply contains a Key and value

so far the code is

ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> map1
                = objectMapper.readValue(response, new TypeReference<Map<String,Object>>(){});
        logger.info("-----------" map1.get("content"));

not sure how to convert the map1 to another map and fetch the value for plan_id. if any other short cut please let me know.

response map

CodePudding user response:

I have mocked some data you have provided as below.

Debug values

In order to retrieve the values for the "plan_id" key I do use this code.

for(var values : map.values()) {
    if(values.containsKey("plan_id")) {
        // return values for 'plan_id' key.
    }
}

CodePudding user response:

If you don't want to create model objects for your response (and nested objects) you could use object mapper to read read the value as a JsonNode and then either use get or a jsonPtrExpr to get the exact value you want. Here are a couple of examples of that:

Example Json:

{
  "map1" : {
    "headers" : {},
    "content" : {
      "account" : {},
      "email" : {},
      "plan_id" : {
        "target_key" : "target_value"
      }
    }
  }
}

JsonNode with get

    JsonNode outerNode = mapper.readValue(jsonStringContents, JsonNode.class);
    // JsonNode with get
    String targetValueWithGet = outerNode.get("map1").get("content").get("plan_id").get(
            "target_key").asText();
    System.out.println("JsonNode with get: "   targetValueWithGet);

JsonNode with jsonPtrExpr

    JsonNode outerNode = mapper.readValue(jsonStringContents, JsonNode.class);
    // JsonNode with jsonPtrExpr
    String targetValueWithJsonPtrExpr = outerNode.at("/map1/content/plan_id/target_key").asText();
    System.out.println("JsonNode with jsonPtrExpr: "   targetValueWithJsonPtrExpr);

The outputs are:

JsonNode with get: target_value
JsonNode with jsonPtrExpr: target_value

Links:

JsonNode get: https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/JsonNode.html#get(java.lang.String)

JsonNode at: https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/JsonNode.html#at(com.fasterxml.jackson.core.JsonPointer)

JsonPointer (expression passed into at): https://fasterxml.github.io/jackson-core/javadoc/2.7/com/fasterxml/jackson/core/JsonPointer.html

The at method will return a node with isMissingNode() == true if the path doesn't exist, so if you're unsure that the structure will always be the same from your response, you'll probably want to check that

This is from the documentation linked (for at):

Node that matches given JSON Pointer: if no match exists, will return a node for which isMissingNode() returns true.

When this occurs your asText will return null, so you'll want to handle that case (either by checking isMissingNode() before calling asText() or checking if asText() is null)

    JsonNode outerNode = mapper.readValue(jsonStringContents, JsonNode.class);
    JsonNode targetNode = outerNode.at("/incorrect/path");
    System.out.println("Is missing node = "   targetNode.isMissingNode());
    String textFromMissingNode = targetNode.asText();

Which outputs:

Is missing node = true
asText value after calling on missing node = 
  • Related