diff --git a/json-modules/json-2/pom.xml b/json-modules/json-2/pom.xml
index ecffd719c7..ee58ab8b25 100644
--- a/json-modules/json-2/pom.xml
+++ b/json-modules/json-2/pom.xml
@@ -108,6 +108,17 @@
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
diff --git a/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java b/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java
new file mode 100644
index 0000000000..f8d38106fd
--- /dev/null
+++ b/json-modules/json-2/src/main/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetter.java
@@ -0,0 +1,87 @@
+package com.baeldung.jsonvaluegetter;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class JSONObjectValueGetter {
+
+ /**
+ * Get values associated with the provided key in the given JSONObject instance
+ *
+ * @param jsonObject JSONObject instance in which to search the key
+ * @param key Key we're interested in
+ *
+ * @return List of values associated with the given key, in the order of appearance.
+ * If the key is absent, empty list is returned.
+ */
+ public List getValuesInObject(JSONObject jsonObject, String key) {
+ List accumulatedValues = new ArrayList<>();
+ for (String currentKey : jsonObject.keySet()) {
+ Object value = jsonObject.get(currentKey);
+ if (currentKey.equals(key)) {
+ accumulatedValues.add(value.toString());
+ }
+
+ if (value instanceof JSONObject) {
+ accumulatedValues.addAll(getValuesInObject((JSONObject)value, key));
+ } else if (value instanceof JSONArray) {
+ accumulatedValues.addAll(getValuesInArray((JSONArray)value, key));
+ }
+ }
+
+ return accumulatedValues;
+ }
+
+ /**
+ * Get values associated with the provided key in the given JSONArray instance
+ *
+ * @param jsonArray JSONArray instance in which to search the key
+ * @param key Key we're interested in
+ *
+ * @return List of values associated with the given key, in the order of appearance.
+ * If the key is absent, empty list is returned.
+ */
+ public List getValuesInArray(JSONArray jsonArray, String key) {
+ List accumulatedValues = new ArrayList<>();
+ for (Object obj : jsonArray) {
+ if (obj instanceof JSONArray) {
+ accumulatedValues.addAll(getValuesInArray((JSONArray)obj, key));
+ } else if (obj instanceof JSONObject) {
+ accumulatedValues.addAll(getValuesInObject((JSONObject)obj, key));
+ }
+ }
+
+ return accumulatedValues;
+ }
+
+ /**
+ * Among all the values associated with the given key, get the N-th value
+ *
+ * @param jsonObject JSONObject instance in which to search the key
+ * @param key Key we're interested in
+ * @param N Index of the value to get
+ *
+ * @return N-th value associated with the key, or null if the key is absent or
+ * the number of values associated with the key is less than N
+ */
+ public String getNthValue(JSONObject jsonObject, String key, int N) {
+ List values = getValuesInObject(jsonObject, key);
+ return (values.size() >= N) ? values.get(N - 1) : null;
+ }
+
+ /**
+ * Count the number of values associated with the given key
+ *
+ * @param jsonObject JSONObject instance in which to count the key
+ * @param key Key we're interested in
+ *
+ * @return The number of values associated with the given key
+ */
+ public int getCount(JSONObject jsonObject, String key) {
+ List values = getValuesInObject(jsonObject, key);
+ return values.size();
+ }
+}
diff --git a/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java b/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java
new file mode 100644
index 0000000000..fc17e700eb
--- /dev/null
+++ b/json-modules/json-2/src/test/java/com/baeldung/jsonvaluegetter/JSONObjectValueGetterUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.jsonvaluegetter;
+
+import org.apache.commons.io.IOUtils;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+public class JSONObjectValueGetterUnitTest {
+
+ private static JSONObject jsonObject;
+ private static JSONObjectValueGetter jsonObjectValueGetter = new JSONObjectValueGetter();
+
+ @BeforeAll
+ public static void loadJsonContent() throws IOException {
+ InputStream inputStream = JSONObjectValueGetterUnitTest.class.getClassLoader().getResourceAsStream("employee.json");
+ String jsonString = IOUtils.toString(inputStream, "UTF-8");
+ jsonObject = new JSONObject(jsonString);
+ }
+
+ @Test
+ public void getValueDirectly() {
+ JSONArray family = jsonObject.getJSONArray("family");
+ JSONObject sonObject = family.getJSONObject(1);
+ JSONObject sonData = sonObject.getJSONObject("son");
+ String sonName = sonData.getString("name");
+ Assertions.assertEquals(sonName, "Peter");
+ }
+
+ @Test
+ public void getAllAssociatedValuesRecursively() {
+ List values = jsonObjectValueGetter.getValuesInObject(jsonObject, "son");
+ Assertions.assertEquals(values.size(), 1);
+
+ String sonString = values.get(0);
+ Assertions.assertTrue(sonString.contains("Peter"));
+ Assertions.assertTrue(sonString.contains("Schoolboy"));
+ Assertions.assertTrue(sonString.contains("11"));
+
+ values = jsonObjectValueGetter.getValuesInObject(jsonObject, "name");
+ Assertions.assertEquals(values.size(), 3);
+
+ Assertions.assertEquals(values.get(0), "Bob");
+ Assertions.assertEquals(values.get(1), "Alice");
+ Assertions.assertEquals(values.get(2), "Peter");
+ }
+
+ @Test
+ public void getNthValueRecursively() {
+ Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 1), "Bob");
+ Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 2), "Alice");
+ Assertions.assertEquals(jsonObjectValueGetter.getNthValue(jsonObject, "name", 3), "Peter");
+ Assertions.assertNull(jsonObjectValueGetter.getNthValue(jsonObject, "nonExistingKey", 1));
+ }
+
+ @Test
+ public void getCountRecursively() {
+ Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "name"), 3);
+ Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "age"), 3);
+ Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "occupation"), 1);
+ Assertions.assertEquals(jsonObjectValueGetter.getCount(jsonObject, "nonExistingKey"), 0);
+ }
+}
diff --git a/json-modules/json-2/src/test/resources/employee.json b/json-modules/json-2/src/test/resources/employee.json
new file mode 100644
index 0000000000..095190212a
--- /dev/null
+++ b/json-modules/json-2/src/test/resources/employee.json
@@ -0,0 +1,30 @@
+{
+ "name" : "Bob",
+ "profession" : "Software engineer",
+ "department" : "Research",
+ "age" : 40,
+ "family" : [
+ {
+ "wife" : {
+ "name" : "Alice",
+ "profession" : "Doctor",
+ "age" : 38
+ }
+ },
+ {
+ "son" : {
+ "name" : "Peter",
+ "occupation" : "Schoolboy",
+ "age" : 11
+ }
+ }
+ ],
+ "performance" : [
+ {
+ "2020" : 4.5
+ },
+ {
+ "2021" : 4.8
+ }
+ ]
+}
\ No newline at end of file