27

I am trying to deserialize my own class with a null value. But my code doesn't work.

My json:

{"Text":null,"Code":0,"Title":"This is Sparta!"}

In my method I do the following:

this.setText(gson.fromJson(jsonObject.getString("Text"), String.class));
this.setTitle(gson.fromJson(jsonObject.getString("Title"), String.class));
this.setCode(gson.fromJson(jsonObject.getString("Faccode"), Integer.class))

I am not deserialize the whole object, because there can be a List<T>, too.

The error:

myapp W/System.err? com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 6 path $
myapp W/System.err? at com.google.gson.Gson.assertFullConsumption(Gson.java:786)
myapp W/System.err? at com.google.gson.Gson.fromJson(Gson.java:776)
myapp W/System.err? at com.google.gson.Gson.fromJson(Gson.java:724)
myapp W/System.err? at com.google.gson.Gson.fromJson(Gson.java:696)
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
BHuelse
  • 2,889
  • 3
  • 30
  • 41

2 Answers2

46

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);
Community
  • 1
  • 1
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77
  • 8
    I have read alot, now. And I tried Gson gson = new GsonBuilder().serializeNulls().create();, too. But didn't get it. How I have to parse it correctly? And the problem is not at serializing, but in DEserializing – BHuelse Oct 30 '15 at 14:41
  • I edited my answer. I hope it will help. Otherwise can you provide more detail ? – ThomasThiebaud Oct 30 '15 at 14:53
  • Now it works. I used the JsonParser, too. But I have JSONObject instead of JsonObject from old code. – BHuelse Oct 30 '15 at 15:11
  • Cool ;) `JSONObject` comes from `org.json.JSONObject` and `JsonObject` from `com.google.gson.JsonObject`. I did not think about this error. – ThomasThiebaud Oct 30 '15 at 15:14
  • 1
    After some testing I have some little fixes to your code. Dont use JsonElement with toString() and dont compare to null. This line works fine this.setText((nullableText instanceof JsonNull) ? "" : jsonObject.get("Text").getAsString()); – BHuelse Oct 30 '15 at 15:38
  • 23
    `.serializeNulls()` part is irrelevant, it is only related to serialization (objects -> json), not vice versa. – Denys Kniazhev-Support Ukraine Jul 14 '16 at 11:12
7

I had a similar problem (an exception thrown on null value) with the following POJO:

public class MyElement {
    private String something;
    private String somethingElse;
    private JsonObject subEntry; // this doesn't allow deserialization of `null`!
}

and this code:

parsedJson = gson.fromJson(json, MyElement.class)

when subEntry returned by the backend was null.

I fixed it by changing the type of subEntry from JsonObject to JsonElement which is a parent class of both JsonObject and JsonNull, to allow deserialization of null values.

public class MyElement {
    private String something;
    private String somethingElse;
    private JsonElement subEntry; // this allows deserialization of `null`
}

To later check for null at runtime, you'd do as follows:

if (parsedJson.subEntry instanceof JsonNull) {
    ...
} else {
    ...
}
jakub.g
  • 38,512
  • 12
  • 92
  • 130
  • See also [this answer](https://stackoverflow.com/questions/12379405/cant-cast-jsonnull-to-jsonobject) – jakub.g Jul 25 '17 at 16:01