Gson to convert JSON to Object that contain HastMap of Objects? - android

I have a problem that I have no idea about this, can anyone help me:
Ex we have a json:
{
"status":"0",
"result": {
"object1": {
"name":"name1",
"age":"21"
},
"object2": {
"event":"new year",
"date":"date"
},
"object1_1": {
"name":"name2",
"age":"22"
},
"object2_1": {
"event":"birthday",
"date":"date"
}
}
}

you can try convert to object by using jackson json.
http://jackson.codehaus.org/

If you want to deserialize this json to an object that contains a Map (and the map contains litteral values and other maps). Assuming you have a bean similar to :
class MyBean {
int status;
Map<String, Object> result;
}
MyBean myBean = new Gson().fromJson(jsonString, MyBean.class);
It should work with no modification. Note that if the type of status is not a number I'm not sure Gson does the conversion as in the json string the value is quoted, same thing applies to your "age" property.
You can also have a look at Genson library http://code.google.com/p/genson/ it has most Gson features, other ones that no other library provide and has better performances. Have a look at the wiki http://code.google.com/p/genson/wiki/GettingStarted.
EDIT
Are the names really things like object1_1, object2_1 etc? When looking at the structure I imagine that object1 goes with object2 and so long. If you use gson you can write a custom TypeAdapter http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/TypeAdapter.html.
So you can create a root object similar to
class Response {
int status;
List<MyObject> result;
}
class MyObject {
String name;
int age;
String event;
String date;
}
In the read method of your TypeAdapter you should compose instances of MyObject based on the keys (object1 with object2, object1_1 with object2_1...) or take a similar approach.
If you want more details on how to do that you can also ask on Gson google group.

Related

Best Way to Create Room Database Object

I am New to Room Persistence Library in Android. I have looked into a lot of tutorials related to Room. But something is unclear about it.
I can relate my questions to the below response. If we use #Embedded in "Info", Is it possible to declare info POJO class as separate entity? because inside info I have another object called "preferences". How can I embed that to my Room Database ?
Next is How can I use Awb ArrayList in below sample for Type converters? Note that inside Awb ArrayList has one more "terms" array inside.
I would appreciate if some can show and explain to me the best way to Create Room from the below sample data. I know so many tutorials are there for simple JSON structure, but I didn't find any examples with nested JsonObjects.
{
"hashCode": 10461,
"jobs": [
{
"info": {
"jobDesc": "aaaaa",
"signatureRequired": "true”
"preferences": {
"podRequired": 0,
"eligableForCcod": false,
"signatureRequired": 1
}
},
"awb": [
{
"terms": [
{
"termValue": "INR1500.000",
"termType": "CASH_AMOUNT"
},
{
"termValue": "CTLDk",
"termType": "CX_EN"
}
],
"packagesCount": 1,
"accountId": "AE _MP",
"awb": "1234567878440"
}
]
}
]
}
I don't know if this is the best possible approach, but normally when I have complex objects in Room I define a converter class containing two TypeConverters. The first one converts from the structured object (your POJO class) to a String with GSON library, something like:
#TypeConverter
public String fromPojoToString(MyPojoClass info) {
if (info == null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<MyPojoClass>() {
}.getType();
return gson.toJson(info, type);
}
The second converter converts from the string (stored inside Room) to the structured object (the POJO class). Something like:
#TypeConverter
public MyPojoClass fromStringtoPojo(String object) {
if (object == null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<MyPojoClass>() {
}.getType();
return gson.fromJson(info, type);
}
This way you'll be able to serialize/deserialize your POJO class without writing a lot of boilerplate. Obviously, you have to annotate your AppDatabase class (the one that extends RoomDatabase) with your Converter using #TypeConverters annotation.
There is a good article about this approach here https://medium.com/#toddcookevt/android-room-storing-lists-of-objects-766cca57e3f9.
Hope that this helps, best luck!
Explore these link to easy understand room persistance database
https://www.youtube.com/watch?v=KAHAQunQkDE
https://developer.android.com/topic/libraries/architecture/adding-components#room
https://developer.android.com/training/data-storage/room/

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();
}

Reading data from json and saving it in android app using ormlite

I am new in doing work with android database. My question is, I have a json data which i want to parse it in my android application. Specifically i want to take that data and save it in my app database which is ORMLITE.
Does anyone have any example of this so please do share with me. Any kind of video tutorial or anything will be helpful here.
Thanks in advance
I would utilize the GSON library which is super helpful for handling JSON
https://code.google.com/p/google-gson/
Then you need to create a java class with all of the data that the JSON has that you want to parse.
If your JSON looked like this:
{
"id":4854
"name":"Charlie"
"age":35
"eye_color":"blue"
}
Then you would want to create a class matching that data. THIS IS CASE SENSITIVE.
public class Data implements Serializable {
private int id;
private String name;
private int age;
private String eye_color;
}
public class Item implements Serializable{
}
Now you can create a java object from the JSON:
Gson gson = new Gson();
Data data = gson.fromJson(yourJsonHere, Data.class)
and boom! your data object is now what your JSON was.
Ok, I don't use ORMLITE, I'm using GreenDao as ORM but I guess it's the same thing. For parsing a JSON there is some libraries that help, I always try to use GSON that is a library that handle serialization between objects and JSON data. There is a lot of documentation about GSON on the web and plenty of examples. Search for it. I recommend use that approach, for me is the better. Also you can parse a JSON with the org.json.JSON library. This one is more "by hand" parser but could be pretty useful. For example:
for the following JSON:
{
"name": "MyName",
"age": 24
}
that you want to map into a object Person that is a class from your data model generated by ORMLITE:
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
You could do something like:
Person myPerson = new Person();
//This is the use of the org.json.JSON library
JSONObject jObject = new JSONObject(myJSONString);
myPerson.setName(jObject.getString("name"));
myPerson.setAge(jObject.getInt("age"));
And that's a way. Of course JSON library has many function and types to help you with JSON data. Check it out.
But all that code with GSON will be reduced to:
Gson gson = new GsonBuilder().create();
Person myPerson = gson.fromJson(myJSONString, Person.class);
So again try using GSON, it's the best way. Hope it helps

how to parse array inside object through gson in android

I want to parse array inside object through GSON.. for Example
{
'title': 'Java Puzzlers: Traps, Pitfalls, and Corner Cases',
'isbn': '032133678X',
'authors':[
{
'id': 1,
'name': 'Joshua Bloch'
},
{
'id': 2,
'name': 'Neal Gafter'
}
]
}
I am only able to parse only object i.e. title, ISBN and got its value but i don't know how to get the value of authors? Please help ,I am using JSON parsing through GSON in android..
ArrayList<Authors> lAuthors = new ArrayList<Authors>();
List<Authors> list = new Gson().fromJson(json, lAuthors.getClass());
for (Object a : list)
{
System.out.println(a);
}
This will give you values in class Author's object.
public class Author{
int id;
String name;
//getter setter here
}
Hope it helps.
those are usefull links for Nasted JSON parsing examples :
Parsing JSON nested array with GSON on Android
http://www.javacreed.com/simple-gson-example/

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