Introducing variables to Gson - android

I have a large JSON file that contains A LOT of similar code. It's similar to this:
...,"techs":{"t1":{"level":24,"able":true},"t2":{"level":23,"able":true},"t3":{"level":20,"able":true},"t4"...,"t5"...
It has since t1 until t510... For this reason, I have to create an activity for each tN, so I have to create 510 activities! 0.0
To get acces to each tN I use the following lines:
Gson gson = new Gson();
Planets json = gson.fromJson(str, Planets.class);
System.out.println(json.techs.t1.level);
System.out.println(json.techs.t2.level);
etc...
So I wanna know if there's the possibility to change t1 for a variable, so that I only have to change the variable to access t2 in a single activity.
For example: String tech = t456; System.out.println(json.techs.tech.level);
Thank you very much in advance!

It's all just about your imagination ;-)
I will come out from this JSON snippet
"techs":{"t1":{"level":24,"able":true},"t2":{"level":23,"able":true},"t3":{"level":20,"able":true}}
This is easily representable as this structure
HashMap<String, InnerObject>
where InnerObject class is defined like this:
class InnerObject {
int level;
boolean able;
}
So everything you need is class, where single field will be called techs and it will be defined like this:
class JSONWrapper {
// another variables
HashMap<String, InnerObject> techs;
}
To access fields after, you can use:
String techId = "t546";
InnerObject = JSONWrapperInstance.techs.get(techId);
Whole code:
String str = "... contains JSON string ...";
JSONWrapper JSONWrapperInstance = new Gson().fromJson(str, JSONWrapper.class);
And you can walk through all items in HashMap like this:
Iterator<String> iterator = JSONWrapperInstance.techs.keySet().iterator();
while(iterator.hasNext()){
InnerObject = JSONWrapperInstance.techs.get(iterator.next());
}

Related

How to remove specific collections from a JSON with Gson in Shared Preferences?

I want to remove attributes that I specify collections using Gson.
My code:
SharedPreferences sharedPreferences = parentActivity.getSharedPreferences(Accommodation.UPLOAD_ACCOMMODATION_DETAILS_ALL, MODE_PRIVATE);
// Get saved string data in it.
String userInfoListJsonString = sharedPreferences.getString(Accommodation.UPLOAD_ACCOMMODATION_DETAILS, "");
// Create Gson object and translate the json string to related java object array.
Gson gson = new Gson();
Accommodation userInfoDtoArray = gson.fromJson(userInfoListJsonString, Accommodation.class);
// Loop the UserInfoDTO array and print each UserInfoDTO data in android monitor as debug log.
// Get each user info in dto.
Accommodation userInfoDto = userInfoDtoArray;
I printed Json and it have this:
{"accommodationName1":"Green Flat",
"accommodationName2":"Bangolor",
"accommodationName3":"GHost house",
"imgAccommodation1":"/data/user/0/com.xxx.xxx/cache/cropped6900224487159235524.jpg",
"imgAccommodation2":"/data/user/0/com.xxx.xxx/cache/cropped3411178797945328810.jpg",
"imgAccommodation3":"/data/user/0/com.xxx.xxx/cache/cropped9128365945226539316.jpg"}
I can use this code to get the value:
userInfoDto.accommodationName1;
It show the value :
Green Flat
So how I can remove the specific collection of that value?

Iterate through Java jsonObjects without array included

My problem is that this will create 3 new instances of DailyJobObjects with the same values as object number one (01, Bill, 50). And it's logical that it would do so, so how can I iterate through my jsonObject so I can separate the three objects? I have looked this up tirelessly but everything thing I have seen has and array included in the jsonData which would make things easier but this response Body is coming straight from a database - no arrays, just back to back objects. Iterating only gives me keys which I already did in a separate method to give me one half of my map. Now I need the values. You don't have to give me an answer, you can (I rather) point to something I'm missing. Thanks!
{"id":"01","name":"Bill","salary":"50"},
{"id":"02","name":"James","salary":"60"},
{"id":"03","name":"Ethan","salary":"70"}
JSONObject fields = new JSONObject(jsonData);
mObjectArray = new DailyJobObjectArray[fields.length()];
for(int i=0; i< fields.length(); i++) {
DailyJobObject mObject = new DailyJobObject();
mObject.setName(fields.getString("name"));
mObject.setSalary(fields.getString("salary"));
mObjectArray[i] = mObject;
}
return mObjectArray;
As #Selvin has mentioned, your json is not valid. Either get proper json from the database or parse it in a non-standard way. I would suggest getting a proper json array from the DB.
String[] splitString = jsondata.split("[^a-zA-Z \\{\\}]+(?![^\\{]*\\})");
for ( String s : splitString) {
try {
JSONObject field = new JSONObject(s);
String name = field.getString("name");
String id = field.getString("id");
} catch (JSONException e) {
e.printStackTrace();
}
}
I also agree that your mObject(...) does not make sense at all
Maybe you're looking for something like this
mObject.setName(name)

How to structure a Map from Json that has duplicate keys

Ok so I have this piece of JSON that I want to parse with Gson. I would like the Strings to be the values and the longs to be the keys.
{"completed_questions":[["String",12345],...]}
The issue is the data type, when I try a Map<String, Long> it parses everything but gives me an error because of the duplicate String keys.
I tried to reverse it thinking Gson would know to switch them around but when I tried Map<Long, String> I got an error about not being able to parse my Strings as Longs.
To get it to work I created a swap map class that takes the Key and Value types and swaps them like so public class SwapMap<K, V> implements Map<K, V> however translating the swapped map actions like put/get/remove seem to be pretty difficult to make work.
What's the best way to parse this with Gson even though the strings aren't unique? (But the numbers are)
JSON doesn't allow identical keys on the same level in a json object. It seems like you are trying to map a json array to a java map.
Based on the following data structure, you would need a list if you want to use the default conversion provided by Gson.
{
"completed_questions": [
[
"String",
12345
],
[
"String",
12345
]
]
}
Here is a quick implementation:
private static void mapToObject() {
String json = "{\"completed_questions\":[[\"String\",12345],[\"String\",123456]]}";
Gson gson = new Gson();
CompletedQuestions questions = gson.fromJson(json, CompletedQuestions.class);
for (List<String> arr : questions.getCompleted_questions()) {
for (String val : arr) {
System.out.print(val + " ");
}
System.out.println();
}
}
public static class CompletedQuestions {
List<List<String>> completed_questions;
public List<List<String>> getCompleted_questions() {
return completed_questions;
}
}
This outputs:
String 12345
String 123456
The thing to note is that I am using a list for mapping purposes which closely resembles the data model provided.
This will require you to do the conversion to long yourself. But the way that json string looks. It seems like you would need to operate on the indices. If you have control over the json structure, I would recommending creating a better model. Other wise you can do something like list.get(0) -> your key list.get(1) -> your value which is the long on the inner list.
So what I did is just made a custom Gson Deserializer that mapped these values to a LongSparseArray<String>, which is the best way to go about it.
This is the relevant parts of the Deserializer:
for (JsonElement array : jsonObject.get("my_key").getAsJsonArray()) {
if (array.getAsJsonArray().size() == 2) {
String value = array.getAsJsonArray().get(VALUE).getAsString();
long key = array.getAsJsonArray().get(KEY).getAsLong();
progress.completedActivities.put(key, value);
}
}
Then I just added it to my Gson creator like so:
#Provides #Singleton Gson provideGson() {
return new GsonBuilder()
.registerTypeAdapter(MyClass.class, new MyClass())
.create();
}

Convert from JSONArray to ArrayList<CustomObject> - Android

I converted an ArrayList to an JSONArray. How can I convert it back?
The final result must be an ArrayList. Thank you in advance.
EDIT:
This is how I convert the ArrayList to JSONArray:
String string_object= new Gson().toJson(MyArrayList<OBJECT>);
JSONArray myjsonarray = new JSONArray(string_object);
You can convert your JsonArray or json string to ArrayList<OBJECT> using Gson library as below
ArrayList<OBJECT> yourArray = new Gson().fromJson(jsonString, new TypeToken<List<OBJECT>>(){}.getType());
//or
ArrayList<OBJECT> yourArray = new Gson().fromJson(myjsonarray.toString(), new TypeToken<List<OBJECT>>(){}.getType());
Also while converting your ArrayList<OBJECT> to JsonArray, no need to convert it to string and back to JsonArray
JsonArray myjsonarray = new Gson().toJsonTree(MyArrayList<OBJECT>).getAsJsonArray();
Refer Gson API documentation for more details. Hope this will be helpful.
JSONArray is just a subclass of object, so if you want to get the JSONObjects out of a JSONArray into some other form, JSONArray doesn't have any convenient way to do it, so you have to get each JSONObject and populate your ArrayList yourself.
Here is a simple way to do it:
ArrayList<JSONObject> arrayList = new ArrayList(myJSONArray.length());
for(int i=0;i < myJSONArray.length();i++){
arrayList.add(myJSONArray.getJSONObject(i));
}
EDIT:
OK, you edited your code to show that you are using GSON. That is a horse of a different color. If you use com.google.gson.JsonArray instead of JSONArray, you can use the Gson.fromJson() method to get an ArrayList.
Here is a link: Gson - convert from Json to a typed ArrayList
Unfortunately, this will require a little work on your part. Gson does not support deserializing generic collections of arbitrary objects. The Gson User Guide topic Serializing and Deserializing Collection with Objects of Arbitrary Types list three options for doing what you want. To quote the relevant parts of the guide:
You can serialize the collection with Gson without doing anything specific: toJson(collection) would write out the desired output.
However, deserialization with fromJson(json, Collection.class) will not work since Gson has no way of knowing how to map the input to the types. Gson requires that you provide a genericised version of collection type in fromJson. So, you have three options:
Option 1: Use Gson's parser API (low-level streaming parser or the DOM parser JsonParser) to parse the array elements and then use Gson.fromJson() on each of the array elements. This is the preferred approach. Here is an example that demonstrates how to do this.
Option 2: Register a type adapter for Collection.class that looks at each of the array members and maps them to appropriate objects. The disadvantage of this approach is that it will screw up deserialization of other collection types in Gson.
Option 3: Register a type adapter for MyCollectionMemberType and use fromJson with Collection<MyCollectionMemberType>
This approach is practical only if the array appears as a top-level element or if you can change the field type holding the collection to be of type Collection<MyCollectionMemberType>.
See the docs for details on each of the three options.
we starting from conversion [ JSONArray -> List < JSONObject > ]
public static List<JSONObject> getJSONObjectListFromJSONArray(JSONArray array)
throws JSONException {
ArrayList<JSONObject> jsonObjects = new ArrayList<>();
for (int i = 0;
i < (array != null ? array.length() : 0);
jsonObjects.add(array.getJSONObject(i++))
);
return jsonObjects;
}
next create generic version replacing array.getJSONObject(i++) with POJO
example :
public <T> static List<T> getJSONObjectListFromJSONArray(Class<T> forClass, JSONArray array)
throws JSONException {
ArrayList<Tt> tObjects = new ArrayList<>();
for (int i = 0;
i < (array != null ? array.length() : 0);
tObjects.add( (T) createT(forClass, array.getJSONObject(i++)))
);
return tObjects;
}
private static T createT(Class<T> forCLass, JSONObject jObject) {
// instantiate via reflection / use constructor or whatsoever
T tObject = forClass.newInstance();
// if not using constuctor args fill up
//
// return new pojo filled object
return tObject;
}
Try this,
ArrayList<**YOUCLASS**> **YOURARRAY** =
new Gson().fromJson(oldJSONArray.toString(),
new TypeToken<List<**yourClass**>>(){}.getType());

JSON tag returns empty array [] while gson expects a string

I am using GSON Library to parse my JSON tag.
some of the tags are expected to hold string values (not arrays). the problem is, sometimes the element is empty [] and when it does that the console gives me this error
expected String but was BEGIIN ARRAY.
The following is the ideal case for my JSON
{
"internet": "600.00",
"internet_remarks": "Fibre 1gbps",
}
but sometimes it becomes
{
"internet": "600.00",
"internet_remarks": [],
}
My parsing code is as follows:
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
MainContainer mainContainer = gson.fromJson(obj, MainContainer.class);
while in my class is as follows the varailbas are defined as follows
private String internet;
private String internet_remarks;
My question is what changes should i make so that the variable accommodate the empty array []
If you don't control the source of the (poorly designed) JSON and can't fix it, then you're going to need to write a custom deserializer that constructs your MainContainer object.
See: How do I write a custom deserializer? here on SO and/or the information in the Gson User's guide
If the only time that field is an array type is when it's an empty array, the easiest approach I can think of is simply inspecting the returned JSON and if it's an array, remove it. Then deserialize to your MainContainer. Gson silently ignores any missing elements in the JSON and internet_remarks will be null in your MainContainer.
class MyDeserialier implements JsonDeserializer<MainContainer>
{
#Override
public MainContainer deserialize(JsonElement je, Type type,
JsonDeserializationContext jdc)
throws JsonParseException
{
JsonObject obj = je.getAsJsonObject();
if (obj.get("internet_remarks").isJsonArray())
{
obj.remove("internet_remarks");
}
return new Gson().fromJson(obj, MainContainer.class):
}
}
If that's not actually the case and that array might not be empty, you'll need to add the logic to deal with that and convert it to a String if that's what you really want.
In your case:
The gson parser is confused when you are asking it to parse an array into string.
So, you can change the internet_remarks into an array of string.
Its always a safe approach to use annonations in the container class.
Extras:
When ever you are working with json, these two tools will be handy.
1.OnlineJsonEditor.
2.JsonGen
I would suggest declare your second attribute as an array. i.e.
private String[] internet_remarks;
When you have a single string, still put it in the array.
eg:
{
"internet": "600.00",
"internet_remarks": ["Fibre 1gbps"]
}
When it's empty,
{
"internet": "600.00",
"internet_remarks": []
}
So your json will always be consistent.
Also, I noted that you're not really making use of the GsonBuilder. You could just create the Gson instance with a constructor than a builder.
Gson gson = new Gson();

Categories

Resources