I have a nested json like below. From this I want to get specific values which are not again json objects. e.g. values against keys "first_name
" or "last_name
" or "purpose
" etc
[
{
"purpose":"Audit",
"sender_name":"Tester One",
"sent_date":"10-10-2020",
"approval":true,
"agency":{
"name":"Test Agency",
"id":1234
},
"records":[
{
"students":{
"first_name":"FirstOne",
"last_name":"LastOne",
"address":{
"street":"123 Street",
"city":"Test City",
"zip":12345
}
},
"employees":{
"first_name":"EmpFirst",
"last_name":"EmpLast",
"address":{
"street":"ABC Street",
"city":"ABC City",
"zip":99921
}
}
}
],
"completion":true
}
]
For this I wrote 2 recursive methods and another method which will invoke this method. Following is my code.
public class JsonUtils {
private static ArrayList<Object> resultSet = new ArrayList<Object>();
/*Method to convert json to Map*/
public static Map<String, Object> convertJsonArrayToMap(String filePath) {
List<Object> list = null;
ObjectMapper mapper = new ObjectMapper();
try {
list = mapper.readValue(new File(filePath), new TypeReference<List<Object>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
Map<String, Object> data = (Map<String, Object>) list.get(0);
return data;
}
/*Method to iterate nested HashMap*/
public static Object jsonMapIterator(Map<String, Object> map, String key) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof Map) {
jsonMapIterator((Map<String, Object>) entry.getValue(), key);
} else if (entry.getValue() instanceof ArrayList) {
jsonListIterator((ArrayList<Object>) entry.getValue(), key);
} else {
if (entry.getKey() == key) resultSet.add(entry.getValue());
}
}
return resultSet!=null?resultSet:null;
}
/*Method to iterate array list of objects*/
public static Object jsonListIterator(ArrayList<Object> list, String key) {
AtomicReference<Object> value = null;
Consumer<Object> action = i -> {
if (i instanceof ArrayList) {
jsonListIterator((ArrayList<Object>) i, key);
} else if (i instanceof Map) {
jsonMapIterator((Map<String, Object>) i, key);
} else {
value.set(i);
}
};
list.stream().forEach(action);
return value;
}
/*method to invoke recursive search and return all values for any given key*/
public static Object jsonValueFetcher(Map<String, Object> jsonData, String key){
resultSet.clear();
ArrayList<Object> values;
values = (ArrayList<Object>) jsonMapIterator(jsonData, key);
return values.size()==0?null:values;
}
public static void main(String[] args) {
Map<String, Object> jsonData = convertJsonArrayToMap("src/test/resources/nestedJson.json");
System.out.println(jsonValueFetcher(jsonData,"first_name"));
}
}
Now in here, how can I make the static variable resultSet
and the two recursive methods thread safe in case of a parallel test execution?