How to get data from nested JSON objects using Gson - android

I would like get countynames from the API and it returns nested objects;
"countries": {
"1": {
"name": "Cyprus",
"nameTurkish": "KKTC",
"nameNative": "Kıbrıs"
},
"2": {
"name": "Turkey",
"nameTurkish": "Türkiye",
"nameNative": "Türkiye"
},
"3": {
"name": "Monaco",
"nameTurkish": "Monako",
"nameNative": "Monaco"
},
and so on there are more than 200 countries and every county has its own "NUMBER_ID". In the end I want to list all "name" information. I think I should use JsonDeserializer but unfortunately I couldn't.

The entire JSON response can be read as a JSONObject that has multiple elements in it that you can iterate through and get different data.
String jsonResponse = ""; // Put the entire JSON response as a String
JSONObject root = new JSONObject(jsonResponse);
JSONArray rootArray = root.getJSONArray("countries"); // root element of the json respons
for (int i = 0; i < rootArray.length(); i++) {
JSONObject number = rootArray.getJSONObject(i);
String country = number.getString("name"); // Get country name
// Here you can add `country` into a List
}
UPDATE:
but there is no array in my JSON file, all of them are objects, every
country is in an object and every object has its own SerializedName
You can read it into JSONOjbect, and instead of using a JSONArray, you can iterate over the length of the JSONObject as below.
try {
JSONObject root = new JSONObject(jsonResponse);
JSONObject countries = root.getJSONObject("countries");
for (int i = 1; i <= countries.length(); i++) {
JSONObject number = countries.getJSONObject(String.valueOf(i));
String country = number.getString("name"); // Get country name
// Here you can add the `country` into a List
}
} catch (JSONException e) {
e.printStackTrace();
}

try using TypeToken.
Gson gson = new Gson();
List<Country> list = gson.fromJson(gson.toJson(what_you_get_data), new TypeToken<ArrayList<Country>>(){}.getType()); //Country is VO class what you make.

Here, you can see that your data looks like HashMap, so I just tried in that way and your data parsed successfully without a glitch:
Create Pojo's:
public class Countries {
private HashMap<String, Country> countries;
public HashMap<String, Country> getCountries() { return countries; }
public void setCountries(HashMap<String, Country> countries) { this.countries = countries; }
}
public class Country {
private String name;
private String nameTurkish;
private String nameNative;
public String getName() { return name; }
public void setName(String name) { this.name = name;}
public String getNameTurkish() { return nameTurkish; }
public void setNameTurkish(String nameTurkish) { this.nameTurkish = nameTurkish; }
public String getNameNative() { return nameNative; }
public void setNameNative(String nameNative) { this.nameNative = nameNative; }
}
Create a Gson Object and parse it:
Gson gson = new Gson();
// Countries Object
Type testC = new TypeToken<Countries>(){}.getType();
Countries ob = gson.fromJson(test, testC);
String newData = gson.toJson(ob.getCountries());
System.out.println("New Data: "+newData);
// All country in HashMap
Type country = new TypeToken<HashMap<String, Country>>(){}.getType();
HashMap<String, Country> countryHashMap = gson.fromJson(newData, country);
// Print All HashMap Country
for (Map.Entry<String, Country> set : countryHashMap.entrySet()) {
System.out.println("==> "+set.getKey() + " = " + set.getValue());
}
Output:
I/System.out: ==> 1 = Country{name='Cyprus', nameTurkish='KKTC', nameNative='Kıbrıs'}
I/System.out: ==> 2 = Country{name='Turkey', nameTurkish='Türkiye', nameNative='Türkiye'}
I/System.out: ==> 3 = Country{name='Monaco', nameTurkish='Monako', nameNative='Monaco'}

Related

How to search a key in JSON Object if format is not constant?

In my android application, I have saved my form's data in a json, the parent of this json is a json object that may contains simple key value pairs, or a JSON Array, or sub json object.
The structure of Parent JSON Object is basically changing on run time and i have to add a function that can find value saved against any key.
For example, if I have the following JSON and I want to get value of key5. Is there any way to get the value?
A solution that i want to try is loop through the json but i am unable to check what is stored on index of json object mean is it a simple string, a json array or a sub json object.
{
"key1": "value of key 1",
"key2": "value of key 2",
"key3": "value of key 3",
"subjson": {
"key4": "value of key 4",
"key5": "value of key 5",
"key6": "value of key 6"
},
"subjsonArray": [
{
"key7": "value of key 7",
"key8": "value of key 8"
},
{
"key9": "value of key 9",
"key10": "value of key 10"
}
]
}
Can someone please help me out with this. Any help will be appreciated.
Here is an example to handle json
JsonElement jsonElement = new Gson().fromJson("YOUR JSON", JsonElement.class);
if(jsonElement.isJsonObject()){
jsonElement.getAsJsonObject("key5");
}else if(jsonElement.isJsonArray()){
jsonElement.getAsJsonArray("key5");
}
If you need to iterate over json you can use
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
String key = entry.getKey();
JsonElement value = jsonObject.get(entry.getKey()));
}
You need to import Gson to your project
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
More information how to use Gson:
https://github.com/google/gson
Let me start by saying this - you should try to fix the non-constant Json issue before finding a solution for this.
But if it's out of your control, here's what might work.
This handles nested JsonObject and/or JsonArray.
You can just copy/paste those functions.
All you have to do is call this function - getValueFromNonConstantJson(...)
private void getValueFromNonConstantJson(String fullJson, String key) {
Gson gson = new Gson();
final Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> objectMap = gson.fromJson(fullJson, mapType);
String value = "";
value = getValueFromMap(objectMap, key);
}
private String getValueFromMap(Map<String, Object> objectMap, String key) {
String result = "";
// let's quickly check is the root object contains the key you want
// if it does, you don't have to start the for loop at all
if(objectMap.containsKey("key5")) {
Object key5Value = objectMap.get("key5");
if(key5Value instanceof JsonObject) {
JsonObject jsonObject = (JsonObject) key5Value;
result = getValueFromJsonObject(jsonObject, key);
} else if (key5Value instanceof JsonArray) {
JsonArray jsonArray = (JsonArray) key5Value;
result = getValueFromJsonArray(jsonArray, key);
}
} else {
for(Map.Entry<String, Object> entry : objectMap.entrySet()) {
if(entry.getValue() instanceof JsonObject) {
JsonObject jsonObject = (JsonObject) entry.getValue();
result = getValueFromJsonObject(jsonObject, key);
if(!result.isEmpty()) {
// you found it.
break;
}
} else if (entry.getValue() instanceof JsonArray) {
JsonArray jsonArray = (JsonArray) entry.getValue();
result = getValueFromJsonArray(jsonArray, key);
if(!result.isEmpty()) {
// you found it.
break;
}
}
}
}
return result;
}
private String getValueFromJsonObject(JsonObject subJsonObject, String key) {
String value = "";
Gson gson = new Gson();
final Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> objectMap = gson.fromJson(subJsonObject, mapType);
value = getValueFromMap(objectMap, key);
return value;
}
private String getValueFromJsonArray(JsonArray subJsonArray, String key) {
String value = "";
Gson gson = new Gson();
Object[] objectArr = gson.fromJson(subJsonArray, Object[].class);
for(Object object : objectArr) {
if(object instanceof Map) {
Map<String, Object> objectMap = (Map<String, Object>) object;
value = getValueFromMap(objectMap, key);
if(!value.isEmpty()) {
break;
}
}
}
return value;
}
Using Retrofit, you can achieve it like this :
Below is the Model class which extends JsonElement as the JsonResponse structure is undefined
public class JsonResponse extends JsonElement {
//Key will be of type JsonElement
#SerializedName("key1")
public JsonElement key1;
//Return type is JsonElement since it is decided at Runtime
public JsonElement getKey1() {
if (key1 instanceof JsonArray) {
List<JsonObject> objectList = getArray(key1);
return (JsonElement) objectList; //If key is of type JsonArray then return JsonArray
} else {
return getObject(key1); //If key is of type JsonObject then return JsonObject
}
}
public void setKey1(JsonElement key1) {
this.key1 = key1;
}
private JsonObject getObject(JsonElement data) {
Type type = new TypeToken<JsonObject>() {}.getType();
return new Gson().fromJson(data, type);
}
private List<JsonObject> getArray(JsonElement data) {
Type type = new TypeToken<List<JsonObject>>() {}.getType();
return new Gson().fromJson(((JsonObject) data).get("key1"), type);
}
//Method from super class
#Override
public JsonElement deepCopy() {
return null;
}
}
Same process can be repeated for the keys whose return-type is not defined.
Then in your ClassA you can fetch data by directly accessing key1 element from JsonResponse class.
In your ClassA, check if this element key1 is of type JsonArray or not and fetch data accordingly.
Using JSONObject a possible implementation can be
private Object interateNestedJson(JSONObject jsonObject, String keySearch) {
for (Iterator<String> it = jsonObject.keys(); it.hasNext(); ) {
try {
String jsonKey = it.next();
Object jsonValue = jsonObject.get(jsonKey);
if (jsonValue instanceof JSONArray) {
Object foundInArray = iterateArray((JSONArray) jsonValue, keySearch);
if(foundInArray != null) {
return foundInArray;
}
} else if (jsonValue instanceof JSONObject) {
Object foundInObject = interateNestedJson(jsonObject, keySearch);
if(foundInObject != null) {
return foundInObject;
}
} else {
return jsonValue; // return primitive value
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
private Object iterateArray(JSONArray jsonArray, String keySearch) throws JSONException {
for (int i = 0; i < jsonArray.length(); i++) {
Object jsonObject = jsonArray.get(i);
if (jsonObject instanceof JSONObject) {
Object inNested = interateNestedJson((JSONObject) jsonObject, keySearch);
if (inNested != null) {
return inNested;
}
} else if (jsonObject instanceof JSONArray) {
Object inArray = iterateArray((JSONArray) jsonObject, keySearch);
if (inArray != null) {
return inArray;
}
}
}
return null;
}
And you start the search like this
JSONObject json = new JSONObject(jsonString);
Object value = interateNestedJson(jsonObject, "key5");
I have no time to test this now, if it has an error I'll try to fix it later

How do I get a list of Countries, States and Cities from this JSON?

I have a JSON that contains the names of Countries, their states and cities of those states. Here is the json.
I am able to get all the countries but I can't figure out how to get the states based on the selected country and then cities based on the selected state.
Here is how I got the countries.enter code here
First to load the file from assets:
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("Contries.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
Then to load the countries into an ArrayList.
public void loadCountries(String parent, String child, ArrayList<String> listValue)
{
try {
JSONObject obj = new JSONObject(loadJSONFromAsset());
JSONArray m_jArry = obj.getJSONArray(parent);;
ArrayList<HashMap<String, String>> formList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> m_li;
// listValue = new ArrayList<>();
for (int i = 0; i < m_jArry.length(); i++) {
JSONObject jo_inside = m_jArry.getJSONObject(i);
listValue.add(jo_inside.getString(child));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Then this line finally:
loadCountries("Countries", "CountryName", countries);
After I have selected a country, I want to load its states. maybe something like this:
loadCountries("Pakistan", "StateName", states);
and then:
loadCountries("Islamabad Capital Territory", "CityName", cities);
Any help is greatly appreciated.
Working with JSON can be error-prone. Why don't we model objects around your data and we can do something a little more clearer.
Overview.
Lets' Model your objects
Let's Deserialize your raw json into "Objects"
Then we can "query" our modelled objects!
Step 1 - Modelling.
Note I'm not including constructors, getters, setters and any other boiler plate.
public class Country {
private List<State> states;
private String name;
public Optional<State> getStateByName(String name) {
return States.stream().filter(state -> state.getName().equals(name)).findFirst();
}
}
public class State {
private List<String> cities;
private String name;
public Optional<String> getCityByName(String name) {
return cities.stream().filter(city -> city.equals(name)).findFirst();
}
}
public class CountryDataProvider {
private List<Country> countries;
public CountryDataProvider(String rawData) {
// parse your json to create a List of object Country (tip: Use something like Jackson or Gson to do this for you).
// Ref to part 2
}
public Optional<Country> getCountryByName(String name) {
return countries.stream().filter(country -> country.getName().equals(name)).findFirst();
}
}
Step 2 - Deserialize.
This is a broad topic and To be honest there is a lot of libraries that will do it better and they are really easy to add to your project. Here are a few:
Jackson https://github.com/FasterXML/jackson
GSON https://github.com/google/gson <- My pick.
Step 3 - Query
From here you can do what ever you want
countryData = new CountryDataProvider(data);
Optional<List<String>> countriesInPunjab = countryData.getCountryByName("Pakistan")
.map(country -> country.getStateByName("Punjab")
.map(state -> state.getCities()); // would give you all the cities in Punjab, Pakistan.
The code I have given in my example does use functional and Optional interfaces (in Java 8). Let me know if you want them rewritten in a less functional way.
Here is another solution, not very CPU friendly but it works:
First use this method to get a list of countries:
public void loadCountries(String parent, String child, ArrayList<String> listValue)
{
try {
JSONObject obj = new JSONObject(loadJSONFromAsset());
JSONArray m_jArry = obj.getJSONArray(parent);
// m_jArry;
ArrayList<HashMap<String, String>> formList = new ArrayList<HashMap<String, String>>();
HashMap<String, String> m_li;
// listValue = new ArrayList<>();
for (int i = 0; i < m_jArry.length(); i++) {
JSONObject jo_inside = m_jArry.getJSONObject(i);
listValue.add(jo_inside.getString(child));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Call this method like this:
loadCountries("Countries", "CountryName", countries);
Then use the following method to load the States and Cities.
private void getCitiesByState(String countryName, String stateName)
{
try {
JSONObject json = new JSONObject(loadJSONFromAsset());
JSONArray countriesArray = json.getJSONArray("Countries");
for(int i = 0; i < countriesArray.length(); i++)
{
JSONObject countryJSON = countriesArray.getJSONObject(i);
if(countryJSON.getString("CountryName").equals(countryName))
{
JSONArray statesArray = countryJSON.getJSONArray("States");
states.clear();
for(int j = 0; j < statesArray.length(); j++)
{
JSONObject statesJSON = statesArray.getJSONObject(j);
states.add(statesJSON.getString("StateName"));
if(statesJSON.getString("StateName").equals(stateName))
{
JSONArray citiesarray = statesJSON.getJSONArray("Cities");
cities.clear();
for(int k = 0; k < citiesarray.length(); k++)
{
cities.add(citiesarray.getString(k));
}
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

How to obtain and convert custom json data as strings in android

I've googled around and found many tutorials(duplicates) and tips about json for android, but I find it difficult to perceive. I find it hard to get the score and the names as strings from the following json that I've retrieved from my database. I tried to get the result object first and get the names and scores but not certain how I can get manage to get it from [{},{}].
Are there some easy examples or tips? It sounds silly, but I need your help. I would like to hear from you!
{
"result": [
{
"id": "3",
"name": "Bobby",
"score": "44"
},
{
"id": "2",
"name": "Mike",
"score": "10"
}
]
}
Let,
String s = "{"result": [{"id": "3","name": "Bobby","score": "44"},{"id": "2","name": "Mike","score": "10"}]}";
JSONObject jsonObject = new JSONObject(s);
JSONArray result= jsonObject .getJSONArray("result");
for(int i = 0; i < result.length(); i++) {
JSONObject json = result.getJSONObject(i);
String name = json.getString("name");
String score = json.getString("score");
}
it's so simply
Just do like this
first make a model for according to your need like id, name and score
then use this
JSONObject jObj = new JSONObject(response.toString());
JSONArray results = jObj.getJSONArray("result");
now the values are in array use that array to show values
In json {} means object and [] means array.
First you should create a Json object from your string. Then get result as an array. In result you have tow objects that you can get them with their index.
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray result= jsonObject .getJSONArray("result");
// Now we can iterate through the array
for(int i = 0; i < result.length(); i++) {
JSONObject item = (JSONObject) result.get(i);
String name = item.getString("name");
String score = item.getString("score");
}
Use GSON to deserialize from JSON to a Plain Old Java Object (POJO).
Include GSON library in your Android project:compile 'com.google.code.gson:gson:2.8.0'
Create your JAVA POJO model:
public class MyClass {
#SerializedName("result")
private List mResult;
public List<Result> getResults() {
return mResult;
}
private static class Result {
#SerializedName("id")
private String mId;
#SerializedName("name")
private String mName;
#SerializedName("score")
private String mScore;
public String getId() {
return mId;
}
public String getName() {
return mName;
}
public String getScore() {
return mScore;
}
}
}
Deserialize your JSON to your POJO object:
Gson gson = new Gson();
gson.fromJson(you_json_string, MyClass.class);
Once you have your deserialized object you just need to call your getters:
getResults().get(0).getScore()

Get Specific JSON Object based on TextView

I am a newbie in android developers and
I need help to get a specific object based on a text on TextView and show it on another TextView.
Here is my JSON data:
{
"card_data": [{
"card_id": "123456",
"balance": "100000"
}, {
"card_id": "654321",
"balance": "50000"
}]
}
For example on my TextView1 I have "123456".
How can I display "100000" on TextView2?
First create setter and getter for your json. See below code.
private class CardInfo
{
private String cardId;
private String balance;
public CardInfo(String cardId, String balance) {
this.cardId = cardId;
this.balance = balance;
}
public String getCardId() {
return cardId;
}
public String getBalance() {
return balance;
}
}
Then create JsonParser for your Json Object and add json obj as a CardInfoObj in ArrayList.
private ArrayList<CardInfo> mList = new ArrayList<>();
private void jsonParser()
{
try {
JSONObject jsonObject = new JSONObject("{\n" +
"\t\"card_data\": [{\n" +
"\t\t\"card_id\": \"123456\",\n" +
"\t\t\"balance\": \"100000\"\n" +
"\t}, {\n" +
"\t\t\"card_id\": \"654321\",\n" +
"\t\t\"balance\": \"50000\"\n" +
"\t}]\n" +
"}");
JSONArray jsonArray = jsonObject.getJSONArray("card_data");
for(int i=0;i<jsonArray.length(); i++)
{
JSONObject user = jsonArray.getJSONObject(i);
mList.add(new CardInfo(user.get("card_id").toString(), user.get("balance").toString()));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Now In mList having cardId and balance for each json obj. now get cardinfo obj from mList.
private void setText()
{
CardInfo cardInfo = mList.get(0);// get specfice obj based on your requirement.
mTvCard.setText(cardInfo.getCardId());
mTvBalance.setText(cardInfo.getBalance());
}
You need to know the data type of json field. If balance is Integer type then extract integer from json and convert it to string type using String.valueOf("100000"). Now you can set the value on textfield.

How to extract data from a json object in android

In my application I am receiving a JSON object as
{"secQueList":{"1":"Which is your favorite book?","2":"Who was your childhood hero?","3":"What is your pet's name?","4":"What make was your first car or bike?","5":"What is your favorite color?","6":"Which is your favorite sports team?","7":"What was the name of your school?","8":"What is your mother's maiden name?","9":"Which is your birthplace?","10":"Which is your favourite sport?","11":"Which is your favourite place of visit?"},"que1":null,"ans1":null,"message":null,"fieldErrors":null}
I am not able to figure out how exactly should i parse this object.
I tried using the below code but as this not a JSONArray it throws an exception.
String getParam(String code, String element){
try {
String base = this.getItembyID(code);
JSONObject product = new JSONObject(base);
JSONArray jarray = product.getJSONArray("item");
String param = jarray.getJSONObject(0).getString("name");
return param;
} catch (JSONException e) {
e.printStackTrace();
return "error";
}
}
I recommend you use sites for json formater which show to you the types of json elements as http://json.parser.online.fr/
and
you can use Gson library for parsing json by using pojo class
public class secQueList {
public String que1;
public int ans1;
public String message;
public String nextPage;
public QuestionList secQueList;
}
public class QuestionList {
#SerializedName("1")
public String ques1;
#SerializedName("2")
public int ques2;
#SerializedName("3")
public String ques3;
#SerializedName("4")
public String ques4;
#SerializedName("5")
public String ques5;
#SerializedName("6")
public String ques6;
#SerializedName("7")
public int ques7;
#SerializedName("8")
public String ques8;
#SerializedName("9")
public String ques9;
#SerializedName("10")
public String ques10;
#SerializedName("11")
public String ques11;
}
or you can use parse using built in JSON Object
String jsonBody = the string you want to parse
JSONObject quesJsonBody = new JSONObject(jsonBody);
JSONOBject quesJson = quesJsonBody.getJSONObject("secQueList");
String quesJson1 = quesJson.getString("1");
String quesJson2 = quesJson.getString("2");
String quesJson3 = quesJson.getString("3");
String quesJson4 = quesJson.getString("4");
String quesJson5 = quesJson.getString("5");
String quesJson6 = quesJson.getString("6");
String quesJson7 = quesJson.getString("7");
String quesJson8 = quesJson.getString("8");
String quesJson9 = quesJson.getString("9");
String quesJson10 = quesJson.getString("10");
String quesJson11 = quesJson.getString("11");
String que1 = quesJsonBody.getString("que1");
String ans1 = quesJsonBody.getString("ans1");
String message = quesJsonBody.getString("message");
String fieldErrors = quesJsonBody.getString("fieldErrors");
String base = this.getItembyID(code);
JSONObject product = new JSONObject(base);
JSONOBject secQueListJson = product.getJSONObject("secQueList");
// Get all json keys "1", "2", "3" etc in secQueList, so that we can get values against each key.
Set<Map.Entry<String, JsonElement>> entrySet = secQueListJson .entrySet ();
Iterator iterator = entrySet.iterator ();
for (int j = 0; j < entrySet.size (); j++) {
String key = null; //key = "1", "2", "3" etc
try {
Map.Entry entry = (Map.Entry) iterator.next ();
key = entry.getKey ().toString ();
//key = "1", "2", "3" etc
}
catch (NoSuchElementException e) {
e.printStackTrace ();
}
if (!TextUtils.isEmpty (key)) {
Log.d ("JSON_KEY", key);
String value = secQueListJson.getString(key);
//for key = "1", value = "Which is your favorite book?"
//for key = "2", value = "Who was your childhood hero?"
}
}
Try something like this:
JSONObject jsonObject = new JSONObject(code);
JSONObject jsonObject1 = jsonObject.getJSONObject("secQueList");
for (int i=0;i<jsonObject1.length();i++){
String msg = jsonObject1.getString(String.valueOf(i));
}
You can try to use Gson to parse it. I used code below in my App in similiar case:
ArrayList<String> myArrayList;
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<String>>(){}.getType();
myArrayList= gson.fromJson(code, type);
You have to add gson to your build.grandle to have it working
compile 'com.google.code.gson:gson:2.2.+'
Extract Data from JSON String
public void ReadSMS_JSON(String JSON_String) {
String smsID = "";
String phone = "";
String message = "";
JSONObject jsonResponse = new JSONObject(JSON_String);
JSONArray jsonMainNode = jsonResponse.optJSONArray("tblsms");
if(jsonMainNode.length()>0){
JSONObject jsonChildNode = jsonMainNode.getJSONObject(0);
smsID = jsonChildNode.optString("sms_id");
phone = jsonChildNode.optString("sms_number");
message = jsonChildNode.optString("sms_message");
}
}

Categories

Resources