How to Use Google's Gson API to Deserialize JSON Properly

How do I use Google's Gson API to deserialize JSON properly?

That's not possible. You need to modify your JSON structure to represent object1, object2, etc as items of an array. Right now they are properties of an object of which it's apparently unknown how many of them will be (else you didn't attempt to map it as a List). Gson is smart, but not that smart :)

So, as a basic example, this JSON structure with an array:

{ nodes:
[
{ item1: 'value1a', item2: 'value2a' },
{ item1: 'value1b', item2: 'value2b' },
{ item1: 'value1c', item2: 'value2c' }
]
}

in combination with the Java representation (which is not necessarily to be called POJO, but just javabean or model object or value object).

public class Container {
private List<Node> nodes;
// +getter.
}

public class Node {
private String item1;
private String item2;
// +getters.
}

and this Gson call

Container container = new Gson().fromJson(json, Container.class);

should work.

Update: to be clear, your JSON structure is the problem, not your Java object structure. Assuming that your Java object structure is exactly what you would like to end up with, then your JSON structure should look like follows to get Gson to do its job:

{ jObjects:
[
{ id: 123, jObjects:
[
{ item1: 'value1a', item2: 'value2a' },
{ item1: 'value1b', item2: 'value2b' },
{ item1: 'value1c', item2: 'value2c' }
/* etc... commaseparated */
]
},
{ id: 456, jObjects:
[
{ item1: 'value1d', item2: 'value2d' },
{ item1: 'value1e', item2: 'value2e' },
{ item1: 'value1f', item2: 'value2f' }
/* etc... commaseparated */
]
}
/* etc... commaseparated */
]
}

Only the JsonElement property should be replaced by String, since it's invalid.

Deserialize json in java with gson

If you are using gson library then try this

    Gson gson = new Gson();
MainResponse mainResponse = gson.fromJson(response, MainResponse.class);
List<Race> races = mainResponse.getRaces();
for (Race race : races) {
Log.e("TEST","Race id : " + race.getId());
Log.e("TEST","Race Name : " + race.getName());
}

MainResponse.java

public class MainResponse {

@SerializedName("races")
@Expose
private List<Race> races = null;

public List<Race> getRaces() {
return races;
}

public void setRaces(List<Race> races) {
this.races = races;
}

}

Race.java

public class Race {

@SerializedName("id")
@Expose
private int id;
@SerializedName("mask")
@Expose
private int mask;
@SerializedName("side")
@Expose
private String side;
@SerializedName("name")
@Expose
private String name;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getMask() {
return mask;
}

public void setMask(int mask) {
this.mask = mask;
}

public String getSide() {
return side;
}

public void setSide(String side) {
this.side = side;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

Deserialize a ListT object with Gson?

Method to deserialize generic collection:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

...

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> yourClassList = new Gson().fromJson(jsonArray, listType);

Since several people in the comments have mentioned it, here's an explanation of how the TypeToken class is being used. The construction new TypeToken<...>() {}.getType() captures a compile-time type (between the < and >) into a runtime java.lang.reflect.Type object. Unlike a Class object, which can only represent a raw (erased) type, the Type object can represent any type in the Java language, including a parameterized instantiation of a generic type.

The TypeToken class itself does not have a public constructor, because you're not supposed to construct it directly. Instead, you always construct an anonymous subclass (hence the {}, which is a necessary part of this expression).

Due to type erasure, the TypeToken class is only able to capture types that are fully known at compile time. (That is, you can't do new TypeToken<List<T>>() {}.getType() for a type parameter T.)

For more information, see the documentation for the TypeToken class.

JSON - deserializing client class using Gson

After a weekend of digging through Google code, I found the following code which solves my problem:

public static void main(String[] args) {

GsonFactory factory= new GsonFactory();

DateTest dt = new DateTest(new Date());
String j1 = factory.toString(dt);
System.out.println(j1);
DateTest dt2 = factory.fromString(j1, DateTest.class);
System.out.println(dt2);

}

Hope this will help other people in the future.

How do I use Google Json Parsing API (Gson) to parse some dynamic fields in my json?

You can use custom (de)serialization as Raph Levien suggests, however, Gson natively understands maps.

If you run this you will get the output {"A":"B"}

Map<String, String> map = new HashMap<String, String>();
map.put("A", "B");
System.out.println(new Gson().toJson(src));

The map can now contain your dynamic keys. To read that Json again you need to tell Gson about the type information through a TypeToken which is Gson's way of recording the runtime type information that Java erases.

Map fromJson = 
new Gson().fromJson(
"{\"A\":\"B\"}",
new TypeToken<HashMap<String, String>>() {}.getType());
System.out.println(fromJson.get("A"));

I hope that helps. :)

Deserializing JSON array of objects using GSON

I was complicating things that were not complicated. All I had to do was this:

String json = response.body().toString();
Gson mGson = new Gson();

//where Example is the root of JSON
Example rsp = mGson.fromJson(json, Example.class);

//Entry is the list I needed to access
List <Entry> listOfEntrys= rsp.getFeed().getEntry();

//get value
Log.i("MainActivity", "listaEntrya " + listOfEntrys.get(0).getTitle().get$t());

Using GSON in Android to parse a complex JSON object

The correct way to do it using GSON in the format I'm looking for is:

//somewhere after the web response:
Gson gson = new Gson();

Event[] events = gson.fromJson(webServiceResponse, Event[].class);

//somewhere nested in the class:
static class Event{
String name;
String date;

public String getName()
{
return name;
}

public String getDate()
{
return date;
}

public void setName(String name)
{
this.name = name;
}

public void setDate(String date)
{
this.date = date;
}
}

Google Gson issue with deserializing

As it turned out problem was in obfuscation.

If you're not use @SerializedName annotation result JSON can be like that:

{"a":3436213,"b":"some string","c":{.............},"d":true}

We didn't use it because of it isn't DTO. In this case we using JSON just to store some unimportant internal data. But it was very funny lesson for me.

Deserialize with gson and null values

First, you must read about how to parse using gson. You can find some example here.

Now you know how to parse, you can still have problem with null values. To solve it you must tell gson to (de)serialize null using

Gson gson = new GsonBuilder().serializeNulls().create();

From the serializeNulls() doc

Configure Gson to serialize null fields. By default, Gson omits all fields that are null during serialization.

EDIT (Not tested, based on doc)

In order to get some distinct value you can do

String json = ""; //Your json has a String
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();

//If null, use a default value
JsonElement nullableText = jsonObject.get("Text");
String text = (nullableText instanceof JsonNull) ? "" : nullableText.getAsString();

String title = jsonObject.get("Title").toString();
int code = jsonObject.get("Code").getAsInt();

Otherwise if you have this pojo

public class MyElement {
@SerializedName("Text")
private String text;

@SerializedName("Title")
private String title;

@SerializedName("Code")
private int code;
}

you can parse using

String json = ""; //Your json has a String
Gson gson = new GsonBuilder().serializeNulls().create();
MyElement myElement = gson.fromJson(json, MyElement.class);

Deserializing polymorphic JSON with Gson throwing exception

Well, after some time digging I found out that the problem is not actually deserializing, the problem comes when serializing and having a RuntimeTypeFactory registered as described in the question. If you register a runtimeTypeAdapterFactory and use the same field name to define the class type in the factory and in your pojo, json resulting from serializing pojo to json using GSON with the RuntimeTypeAdapterFactory for a SpecialUser for example will be:

{  
"user":{
"userType":"SPECIAL",
"email":"albert@gmail.com",
"name":"Albert"
"userType":"SPECIAL"
}
}

This will result in the exception described:

com.google.gson.JsonParseException: cannot serialize com.mobile.model.entities.v2.common.User because it already defines a field named userType

because de field userType is repeated in the json due to GSON serializer, which will automatically add a field as declared in the RuntimeTypeAdapterFactory registered for the class BaseUser.



Related Topics



Leave a reply



Submit