JSON array parsing with different types - java

I am using vk.com API and in one method in response I am getting something like this:
{
"ts": 1691519416,
"updates": [
[
6,
2000000024,
586731
],
[
4,
586732,
8243,
2000000024,
1512642885,
"income message",
{
"from": "384574802"
}
]
]
}
The problem is I am using Gson and I don't know what type of array I need to use.
For now I have this:
public class Updates {
public int ts;
public Update[] updates;
}
I don`t know what to put inside/instead of updates array.
Found a solution, thank you guys for answers. I just needed to use generics and a 2 dimensional array. The code of Updates class:
public class Updates {
public int ts;
public <?>[][] updates;
}

You can create your class like:
class Response
{
Timestamp ts;
Updates[] updates;
}
And use GSON:
Response response = gson.fromJson(jsonString, Response.class);

Just need to create a generic array.
private Object<?>[] json;

Related

How to use dynamic json value on my POJO class with Gson?

{
"localeCode": "",
"map": {
"DynamicName1": [],
"DynamicName2": [
{
"date": "2016-05-15T00:00:00",
"seqId": 1,
"status": 10
},
{
"date": "2016-05-16T00:00:00",
"seqId": 83,
"status": 10
}
],
"DynamicName3": [],
"DynamicName4": []
},
"respCode": 100,
"respMsg": "success",
"status": 1
}
How to correctly map this kind of json. If you can see that, Dynamic is a dynamic name. So far I have done this :
public class MapModel {
public MapObject map;
public static class MapObject{
public java.util.Map<String, Student> queryStudent;
public static class Student{
public String date;
public String seqId;
public String status;
}
}
}
But when run the app. I'm getting NullPointerException. Can somebody help me?
You're getting the NullPointerException accessing queryStudent of your MapObject inside your MapModel since it's not correctly filled when you're trying to deserialize your Json.
So to solve your problem look at Gson documentation where you can see:
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:
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.
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.
Register a type adapter for MyCollectionMemberType and use fromJson()
with Collection.
Since your MapObject containts a java.util.Map but your class itself it's not generic, I think that a good approach for your case is create a Deserializer.
Before this try to clean up your class definition, to provide constructors to make the deserializer easy to build. Your POJO classes could be:
Student class
public class Student{
public String date;
public String seqId;
public String status;
public Student(String date, String seqId, String status){
this.date = date;
this.seqId = seqId;
this.status = status;
}
}
MapObject class
Note: I change you Map definition, since in your Json seems that could be multiple students for each DynamicName (look at DynamicName2 from your question), so I use Map<String,List<Student>> instead of Map<String,Student>:
public class MapObject{
public Map<String,List<Student>> queryStudent;
public MapObject(Map<String,List<Student>> value){
this.queryStudent = value;
}
}
MapModel class
public class MapModel {
public MapObject map;
}
Now create a Deserializer for your MapObject:
public class MapObjectDeserializer implements JsonDeserializer<MapObject> {
public MapObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
Map<String,List<Student>> queryStudents = new HashMap<String,List<Student>>();
// for each DynamicElement...
for (Map.Entry<String,JsonElement> entry : json.getAsJsonObject().entrySet()) {
List<Student> students = new ArrayList<Student>();
// each dynamicElement has an Array so convert and add an student
// for each array entry
for(JsonElement elem : entry.getValue().getAsJsonArray()){
students.add(new Gson().fromJson(elem,Student.class));
}
// put the dinamic name and student on the map
queryStudents.put(entry.getKey(),students);
}
// finally create the mapObject
return new MapObject(queryStudents);
}
}
Finally register the Deserializer and parse your Json:
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(MapObject.class, new MapObjectDeserializer());
Gson gson = builder.create();
MapModel object = gson.fromJson(YourJson,MapModel.class);
DISCLAIMER: For fast prototyping I test this using groovy, I try to keep the Java syntax but I can forget something, anyway I think that this can put you on the right direction.
Hope it helps,

Enunciate not working with Generics

My resource is
#GET
#Path("/items")
public MyCollection<Items> getItems()throws Exception{
//Code to return MyCollection<items>
}
My Item class is
#XmlRootElement
public class Item{
private int id;
private String name;
//Have getters and Setters.
}
And My collection class is Generic as below.
public class MyCollection<T> extends MyBaseCollection{
private java.util.Collection<T> items;
private int count;
}
When i try to generate doc using enunciate. The sample Json has only the item and count and the fields of Item class is not getting reflected.
My sample Json generated is
{
"items" : [ {
}, {
}, {
}, {
}, {
}, {
}, {
}, {
} ],
"count" : ...,
}
How to get id,name inside the Item in the generated sample Json?
Thanks.
This is a limitation that i have run into as well, there is no way to specify #TypeHint on a nested object. To support documentation, consider creating a custom collection that defines "items" as a collection of specific class instead of generic.
If you have an idea of how you would want this to work (using the generic type) I suggest submitting enhancement request to Enunciate team.
I have a similar problem where I am returning a Map and I can't #TypeHint this.

Deserialize an array of objects with Gson

I know how to deserialize normal JSON object with "Gson" library but I am facing problem to deserialize an JSON array with several JSON object and arrays. I am trying to get the time in the arrival_time JSON object in this simple below but I don't know how to structure my class to accomplish that. Can someone explain me how to do that?
Simple:
[{"route": 1,
"info": [
{"direction": "Surrey Quays"},
{"stops": [{"stops_name": " Tenison Way"},
{"arrival_time":{
"mon-fri": [ "05:38", "06:07","06:37"],
"sat": ["05:34","06:01","06:31"],
"son": ["06:02","06:34","07:04"]
}
}
]
}
]
}]
You can parse this Json using following structure:
class ArrivalTime {
public List<String> mon_fri;
public List<String> sat;
public List<String> son;
}
class Stop {
public String stop_name;
public ArrivalTime arrival_time;
}
class Info {
public String direction;
public List<Stop> stops;
}
class RouteInfo {
public Integer route;
public List<Info> info;
}
and then use it like this:
Gson gson = new Gson();
RouteInfo[] routes = gson.fromJson(/* your json string*/, RouteInfo[].class);
Arrival times will be available at something like this (it is ugly but I just want you to present the sample structure for this json string):
System.out.println(routes[0].info.get(1).stops.get(1).arrival_time.sat.get(0));
To learn the structure you could use a javascript object or a online builder.
http://www.jsonschema2pojo.org/

Deserializing objects with nested ArrayLists with Gson?

So I'm having some trouble with deserializing some JSON that has nested ArrayLists the root element deserializes okay but the nested ArrayList inside of it (Called mTest) are of null value. First here is the valid JSON.
[
{
"mRecipeName": "FirstRecipe",
"mTest": [
{
"mIngredientName": "TestIngredient1",
"mIngredientAmount": "1",
"mUnit": "tbsp"
},
{
"mIngredientName": "TestIngredient2",
"mIngredientAmount": "2",
"mUnit": "tbsp"
}
],
"mRecipeDescription": "Recipe1"
},
{
"mRecipeName": "SecondRecipe",
"mTest": [
{
"mIngredientName": "TestIngredient1",
"mIngredientAmount": "1",
"mUnit": "tbsp"
},
{
"mIngredientName": "TestIngredient2",
"mIngredientAmount": "2",
"mUnit": "tbsp"
}
],
"mRecipeDescription": "Recipe2"
}
]
Here is the Recipe Class
public class Recipe {
public String mRecipeName; //This values good
public String mRecipeDescription; //This values good
public ArrayList<Test> mTest; //This returns null
}
Here is the Test Class
public class Test {
public String mIngredientName;
public float mIngredientAmount;
public String mUnit;
}
And here is how I'm calling it
//Is there another way to do this? Or does this have to be done for every nested
//ArrayList? If so how?
Gson gson = new Gson();
ArrayList<Recipe> result = gson.fromJson(json, new TypeToken<ArrayList<Recipe>>() {}.getType());
Thank you very much in advance to anyone who replies!
So after another hour of hair tearing I realized that "Test" was coming from the JUnit framework and not my own test class, oh the agony! However, what led me to make a test class in the first place was the fact that it wasn't working and of course mysteriously now it is.

Json array to Java class (deserializing with Gson)

I have Json response (named as jsonResultAsText):
{
"Title": "Hi all",
"IsSecret": false,
"Agents": [
{
"ID": 3,
"Name": "John F"
},
{
"ID": 7,
"Name": "Jack D"
}
]
}
I want to deserialize it using Google's gson library.
I have classes like:
public class JsonResponse {
public String Title;
public boolean IsSecret;
public List<Agent> Agents;
}
public class Agent {
public int ID;
public String Name;
}
I want to get json data into JsonResponse class.
It's the code that I try to achieve:
JsonResponse response =
new Gson().fromJson(jsonResultAsText, JsonResponse.class);
But my Android application gives that classic error: Unfortunately, < app_name > has stopped.
I know that there are plenty examples about serializing/deserializing via gson class, but I could not find similar problem/example.
Thanks in advance.
I solve the problem.
I had forgotten to specify this line on json text I provide (on each element of Agents array):
"Since": "2012-01-07T19:11:01.719"
and in my Agent class:
public class Agent {
public int ID;
public String Name;
public DateTime Since;
}
Sure I have that import: import org.joda.time.DateTime;
When I change data type of Since variable from DateTime to String, problem gone.
Now I can deserialize it.
I am just going to learn how to send DateTime from Asp.Net Web Api to Java via Json.
Thanks for comments.

Categories