Use JSONObject keys() to get the key and then iterate each key to get to the dynamic value.
Roughly the code will look like:
// searchResult refers to the current element in the array "search_result" but whats searchResult?
JSONObject questionMark = searchResult.getJSONObject("question_mark");
Iterator keys = questionMark.keys();
while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();
// get the value of the dynamic key
JSONObject currentDynamicValue = questionMark.getJSONObject(currentDynamicKey);
// do something here with the value...
}
Answer from momo on Stack OverflowUse JSONObject keys() to get the key and then iterate each key to get to the dynamic value.
Roughly the code will look like:
// searchResult refers to the current element in the array "search_result" but whats searchResult?
JSONObject questionMark = searchResult.getJSONObject("question_mark");
Iterator keys = questionMark.keys();
while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();
// get the value of the dynamic key
JSONObject currentDynamicValue = questionMark.getJSONObject(currentDynamicKey);
// do something here with the value...
}
Another possibility is to use Gson (Note, I use lombok here to generates getters/setters, toString, etc):
package so7304002;
import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class JsonDemo {
@Data
private static class MyMap {
private int count;
@SerializedName("more_description")
private String moreDescription;
private int seq;
}
@Data
private static class Product {
private String product;
private int id;
@SerializedName("question_mark")
private Map<String, MyMap> questionMark;
}
@Data
private static class MyObject {
private String status;
@SerializedName("search_result")
private List<Product> searchResult;
}
private static final String INPUT = ""; // your JSON
public static void main(final String[] arg) {
final MyObject fromJson = new Gson().fromJson(INPUT,
new TypeToken<MyObject>(){}.getType());
final List<Product> searchResult = fromJson.getSearchResult();
for (final Product p : searchResult) {
System.out.println("product: " + p.getProduct()
+ "\n" + p.getQuestionMark()+ "\n");
}
}
}
Output:
product: abc
{141=JsonDemo.MyMap(count=141, moreDescription=this is abc, seq=2),
8911=JsonDemo.MyMap(count=8911, moreDescription=null, seq=1)}
product: XYZ
{379=JsonDemo.MyMap(count=379, moreDescription=null, seq=5),
845=JsonDemo.MyMap(count=845, moreDescription=null, seq=6),
12383=JsonDemo.MyMap(count=12383, moreDescription=null, seq=4),
257258=JsonDemo.MyMap(count=257258, moreDescription=null, seq=1)}
In a problem I am working on, I have an endpoint where I will need to receive a JSON object which have a key that might contain different objects depending on the call. The list of possible objects is known in advance, but I am struggling with how best to model it. Splitting the endpoint into multiple is not an option.
The example looks something like this:
outerObject {
...,
key: object1 | object2 | object3
}
object1 {
"a": "a"
"b": "b"
}
object2 {
"c": 2
"d": "d"
}
object3 {
"e": 3,
"f": 4
}If I was writing it in Rust I would use an `enum` with structs for each of the different objects. This is for Java 21, so using sealed types is not yet an option (I might be able to upgrade, but I am not sure if the different
Using either Jackson or Gson I was think of representing it in one of their Json structures and then determining which object fits when the call is made.
Is this the best option or are there any more generic solutions?
java - Retrieving values from nested JSON Object - Stack Overflow
How to parse dynamic nested JSON in Java using JSONObject.keys() - Stack Overflow
Parse nested object Json file in JAVA
How to parse Dynamic nested JSON with same keys and store in JAVA Class - Stack Overflow
Videos
Maybe you're not using the latest version of a JSON for Java Library.
json-simple has not been updated for a long time, while JSON-Java was updated 2 month ago.
JSON-Java can be found on GitHub, here is the link to its repo: https://github.com/douglascrockford/JSON-java
After switching the library, you can refer to my sample code down below:
public static void main(String[] args) {
String JSON = "{\"LanguageLevels\":{\"1\":\"Pocz\\u0105tkuj\\u0105cy\",\"2\":\"\\u015arednioZaawansowany\",\"3\":\"Zaawansowany\",\"4\":\"Ekspert\"}}\n";
JSONObject jsonObject = new JSONObject(JSON);
JSONObject getSth = jsonObject.getJSONObject("LanguageLevels");
Object level = getSth.get("2");
System.out.println(level);
}
And as JSON-Java open-sourced, you can read the code and its document, they will guide you through.
Hope that it helps.
You will have to iterate step by step into nested JSON.
for e.g a JSON received from Google geocoding api
{
"results" : [
{
"address_components" : [
{
"long_name" : "Bhopal",
"short_name" : "Bhopal",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Bhopal",
"short_name" : "Bhopal",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Madhya Pradesh",
"short_name" : "MP",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Bhopal, Madhya Pradesh, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 23.3326697,
"lng" : 77.5748062
},
"southwest" : {
"lat" : 23.0661497,
"lng" : 77.2369767
}
},
"location" : {
"lat" : 23.2599333,
"lng" : 77.412615
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 23.3326697,
"lng" : 77.5748062
},
"southwest" : {
"lat" : 23.0661497,
"lng" : 77.2369767
}
}
},
"place_id" : "ChIJvY_Wj49CfDkR-NRy1RZXFQI",
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
I shall iterate in below given fashion to "location" : { "lat" : 23.2599333, "lng" : 77.412615
//recieve JSON in json object
JSONObject json = new JSONObject(output.toString());
JSONArray result = json.getJSONArray("results");
JSONObject result1 = result.getJSONObject(0);
JSONObject geometry = result1.getJSONObject("geometry");
JSONObject locat = geometry.getJSONObject("location");
//"iterate onto level of location";
double lat = locat.getDouble("lat");
double lng = locat.getDouble("lng");
You can use JSONObject from http://central.maven.org/maven2/org/json/json/20180813/json-20180813.jar
public static void main(String[] args) {
String input="{\r\n" +
" \"Sample_01\": {\r\n" +
" \"class\": \"Tenant\",\r\n" +
" \"A1\": {\r\n" +
" \"class\": \"Application\",\r\n" +
" \"template\": \"http\"\r\n" +
" }\r\n" +
" },\r\n" +
" \"Sample_02\": {\r\n" +
" \"class\": \"Tenant\",\r\n" +
" \"A2\": {\r\n" +
" \"class\": \"Application\",\r\n" +
" \"template\": \"http\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
JSONObject jsonObject = new JSONObject(input);
Set<String> keys =jsonObject.keySet();
for(String key:keys) {
System.out.println("Key :: "+key +", Value :: "+jsonObject.get(key));;
}
}
If you again wants to parse the value of Sample_01 or Sample_02 or Sample_XX Check the instance of jsonObject like if(jsonObject.get(key) instanceof JSONObject) and Reiterate the loop
Extending the answer added by @Deepak. Both approaches are feasible but I preferred Gson as I was already using it.
Using JSONObject
JSONObject jsonObject = new JSONObject(input);
Set<String> keys =jsonObject.keySet();
for(String key:keys) {
System.out.println("Key :: "+key +", Value :: "+jsonObject.get(key));;
}
Using Gson
public static void main(String[] args) {
String json = "{\"Sample_01\":{\"class\":\"Tenant\",\"A1\":{\"class\":\"Application\",\"template\":\"http\",\"serviceMain\":{\"class\":\"Service_HTTP\",\"virtualAddresses\":[\"10.0.1.10\"],\"pool\":\"web_poolddd\"},\"web_poolddd\":{\"class\":\"Pool\",\"monitors\":[\"http\"],\"members\":[{\"servicePort\":80,\"serverAddresses\":[\"192.0.13.10\",\"192.0.14.11\"]}]}}},\"Sample_20\":{\"class\":\"Tenant\",\"A1\":{\"class\":\"Application\",\"template\":\"http\",\"serviceMain\":{\"class\":\"Service_HTTP\",\"virtualAddresses\":[\"10.2.2.2\"],\"pool\":\"web_pool_data\"},\"web_pool_data\":{\"class\":\"Pool\",\"monitors\":[\"http\"],\"members\":[{\"servicePort\":80,\"serverAddresses\":[\"192.0.10.10\",\"192.0.10.11\"]}]}}}}";
Type listType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String,Object> myList = gson.fromJson(json, listType);
JsonParser parser = new JsonParser();
for (Map.Entry<String,Object> m : myList.entrySet())
{
System.out.println("==============");
if(m.getValue() instanceof String){
// get String value
}else{ // if value is an Object
System.out.println("VIP Sec: Name: "+m.getKey());
Map<String,Object> myList1 = gson.fromJson(m.getValue().toString(), listType);
for (Map.Entry<String,Object> m1 : myList1.entrySet())
{
if(!( m1.getValue() instanceof String)){
Map<String,Object> myList2 = gson.fromJson(m1.getValue().toString(), listType);
for (Map.Entry<String,Object> m2 : myList2.entrySet())
{
if(!( m2.getValue() instanceof String)){
Map<String,Object> myList3 = gson.fromJson(m2.getValue().toString(), listType);
for (Map.Entry<String,Object> m3 : myList3.entrySet())
{
if(m3.getKey().equals("virtualAddresses")){
System.out.println("VIP Sec: IP Address: "+m3.getValue());
}
else if(m3.getKey().equals("pool")){
System.out.println("Pool Sec: Name: "+m3.getValue());
}else if(m3.getKey().equals("monitors")){
JsonArray monitors = parser.parse(m3.getValue().toString()).getAsJsonArray();
int count = 0;
while(count < monitors.size()){
String monitor = monitors.get(count).getAsString();
System.out.println("Monitor: "+monitor);
count++;
}
}else if(m3.getKey().equals("members")){
JsonArray members = parser.parse(m3.getValue().toString()).getAsJsonArray();
int count = 0;
while(count < members.size()){
// Parsing as Object to key values by key directly
JsonObject mem = members.get(count).getAsJsonObject();
String port = mem.get("servicePort").getAsString();
System.out.println("Port: "+port);
JsonElement ipAddrs = mem.get("serverAddresses");
if(ipAddrs.isJsonArray()){
JsonArray ips = ipAddrs.getAsJsonArray();
int c = 0;
while(c < ips.size()){
String ip = ips.get(c).getAsString();
System.out.println("IP: "+ip);
c++;
}
}
count++;
}
}
}
}
}
}
}
}
}
}
OUTPUT:
==============
VIP Sec: Name: Sample_01
VIP Sec: IP Address: [10.0.1.10]
Pool Sec: Name: web_poolddd
Monitor: http
Port: 80.0
IP: 192.0.13.10
IP: 192.0.14.11
==============
VIP Sec: Name: Sample_20
VIP Sec: IP Address: [10.2.2.2]
Pool Sec: Name: web_pool_data
Monitor: http
Port: 80.0
IP: 192.0.10.10
IP: 192.0.10.11
Read more about 2nd approach here