可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a JSON result in the following format which JSON Lint shows this as a "Valid Response".
My question is: how do I access the content of "question_mark" since "141", "8911", etc are all dynamic values?
My sample code for accessing value of "product".
//Consider I have the first JSONObject
of the "search_result" array and //I access it's "product" value as below. String product = jsonObject.optString("product"); //where jsonObject is of type JSONObject. //product now contains "abc".
JSON:
{ "status": "OK", "search_result": [ { "product": "abc", "id": "1132", "question_mark": { "141": { "count": "141", "more_description": "this is abc", "seq": "2" }, "8911": { "count": "8911", "more_desc": "this is cup", "seq": "1" } }, "name": "some name", "description": "This is some product" }, { "product": "XYZ", "id": "1129", "question_mark": { "379": { "count": "379", "more_desc": "this is xyz", "seq": "5" }, "845": { "count": "845", "more_desc": "this is table", "seq": "6" }, "12383": { "count": "12383", "more_desc": "Jumbo", "seq": "4" }, "257258": { "count": "257258", "more_desc": "large", "seq": "1" } }, "name": "some other name", "description": "this is some other product" } ] }
My question title "dynamic key" could be wrong but I don't know at this point what's a better name for this issue.
Any help would be greatly appreciated!
回答1:
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" 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... }
回答2:
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 questionMark; } @Data private static class MyObject { private String status; @SerializedName("search_result") private List searchResult; } private static final String INPUT = ""; // your JSON public static void main(final String[] arg) { final MyObject fromJson = new Gson().fromJson(INPUT, new TypeToken(){}.getType()); final List 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)}
回答3:
The same thing can also be done using GSON, but instead of using GSON converter adapter to convert into to POJO. we will parse it manually. which gives us flexibility in case of dynamic JSON data.
let's say the JSON format is like below in my case.
{ "dateWiseContent": { "02-04-2017": [ { "locality": " Cross Madian Cross Rd No 4" } ], "04-04-2017": [ { "locality": "Dsilva Wadi" }, { "locality": " Cross Madian Cross Rd No 4", "appointments": [] } ] } }
in this case the dateWiseContent has dynamic object keys so we will parse this json string using JsonParser class.
//parsing string response to json object JsonObject jsonObject = (JsonObject) new JsonParser().parse(resource); //getting root object JsonObject dateWiseContent = jsonObject.get("dateWiseContent").getAsJsonObject();
get the dynamic keys using Map.Entry
as given below
// your code goes here for (Map.Entry entry : dateWiseContent.entrySet()) { //this gets the dynamic keys String dateKey = entry.getKey(); //you can get any thing now json element,array,object according to json. JsonArray jsonArrayDates = entry.getValue().getAsJsonArray(); int appointmentsSize = jsonArrayDates.size(); for (int count = 0; count
similarly any level of dynamic json can be parsed using Map.Entry
回答4:
An example of using Google Gson
JSON data from the question:
{ "status": "OK", "search_result": [ { "product": "abc", "id": "1132", "question_mark": { "141": { "count": "141", "more_description": "this is abc", "seq": "2" }, "8911": { "count": "8911", "more_desc": "this is cup", "seq": "1" } }, "name": "some name", "description": "This is some product" }, { "product": "XYZ", "id": "1129", "question_mark": { "379": { "count": "379", "more_desc": "this is xyz", "seq": "5" }, "845": { "count": "845", "more_desc": "this is table", "seq": "6" }, "12383": { "count": "12383", "more_desc": "Jumbo", "seq": "4" }, "257258": { "count": "257258", "more_desc": "large", "seq": "1" } }, "name": "some other name", "description": "this is some other product" } ] }
Example code:
import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; public class GsonExercise { public static void main(String[] args) { String jsonString = "{\"status\":\"OK\",\"search_result\":[{\"product\":\"abc\",\"id\":\"1132\",\"question_mark\":{\"141\":{\"count\":\"141\",\"more_description\":\"this is abc\",\"seq\":\"2\"},\"8911\":{\"count\":\"8911\",\"more_desc\":\"this is cup\",\"seq\":\"1\"}},\"name\":\"some name\",\"description\":\"This is some product\"},{\"product\":\"XYZ\",\"id\":\"1129\",\"question_mark\":{\"379\":{\"count\":\"379\",\"more_desc\":\"this is xyz\",\"seq\":\"5\"},\"845\":{\"count\":\"845\",\"more_desc\":\"this is table\",\"seq\":\"6\"},\"12383\":{\"count\":\"12383\",\"more_desc\":\"Jumbo\",\"seq\":\"4\"},\"257258\":{\"count\":\"257258\",\"more_desc\":\"large\",\"seq\":\"1\"}},\"name\":\"some other name\",\"description\":\"this is some other product\"}]}"; JsonObject jobj = new Gson().fromJson(jsonString, JsonObject.class); JsonArray ja = jobj.get("search_result").getAsJsonArray(); ja.forEach(el -> { System.out.println("product: " + el.getAsJsonObject().get("product").getAsString()); JsonObject jo = el.getAsJsonObject().get("question_mark").getAsJsonObject(); jo.entrySet().stream().forEach(qm -> { String key = qm.getKey(); JsonElement je = qm.getValue(); System.out.println("key: " + key); JsonObject o = je.getAsJsonObject(); o.entrySet().stream().forEach(prop -> { System.out.println("\tname: " + prop.getKey() + " (value: " + prop.getValue().getAsString() + ")"); }); }); System.out.println(""); }); } }
Output:
product: abc key: 141 name: count (value: 141) name: more_description (value: this is abc) name: seq (value: 2) key: 8911 name: count (value: 8911) name: more_desc (value: this is cup) name: seq (value: 1) product: XYZ key: 379 name: count (value: 379) name: more_desc (value: this is xyz) name: seq (value: 5) key: 845 name: count (value: 845) name: more_desc (value: this is table) name: seq (value: 6) key: 12383 name: count (value: 12383) name: more_desc (value: Jumbo) name: seq (value: 4) key: 257258 name: count (value: 257258) name: more_desc (value: large) name: seq (value: 1)