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.
CodePudding user response:
I have mocked some data you have provided as below.
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)
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 =