(This post is meant to be a canonical question with a sample answer provided below.)
I'm trying to deserialize some JSON content into a custom POJO type with Gson#fromJson(String, Class)
.
This piece of code
import com.google.gson.Gson;
public class Sample {
public static void main(String[] args) {
String json = "{\"nestedPojo\":[{\"name\":null, \"value\":42}]}";
Gson gson = new Gson();
gson.fromJson(json, Pojo.class);
}
}
class Pojo {
NestedPojo nestedPojo;
}
class NestedPojo {
String name;
int value;
}
throws the follow exception
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
at com.google.gson.Gson.fromJson(Gson.java:724)
at com.google.gson.Gson.fromJson(Gson.java:696)
at com.example.Sample.main(Sample.java:23)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189)
... 7 more
Why can't Gson properly convert my JSON text to my POJO type?
in your json you have an array of nestedPojo so either you change the code
or you change the json string
As the exception message states
while deserializing, Gson was expecting a JSON object, but found a JSON array. Since it couldn't convert from one to the other, it threw this exception.
The JSON format is described here. In short, it defines the following types: objects, arrays, strings, numbers,
null
, and the boolean valuestrue
andfalse
.In Gson (and most JSON parsers), the following mappings exist: a JSON string maps to a Java
String
; a JSON number maps to a JavaNumber
type; a JSON array maps to aCollection
type or an array type; a JSON object maps to a JavaMap
type or, typically, a custom POJO type (not mentioned previously);null
maps to Java'snull
, and the boolean values map to Java'strue
andfalse
.Gson iterates through the JSON content that you provide and tries to deserialize it to the corresponding type you've requested. If the content doesn't match or can't be converted to the expected type, it'll throw a corresponding exception.
In your case, you provided the following JSON
At the root, this is a JSON object which contains a member named
nestedPojo
which is a JSON array. That JSON array contains a single element, another JSON object with two members. Considering the mappings defined earlier, you'd expect this JSON to map to a Java object which has a field namednestedPojo
of someCollection
or array type, where that types defines two fields namedname
andvalue
, respectively.However, you've defined your
Pojo
type as having a fieldthat is neither an array type, nor a
Collection
type. Gson can't deserialize the corresponding JSON for this field.Instead, you have 3 options:
Change your JSON to match the expected type
Change your
Pojo
type to expect aCollection
or array typeWrite and register a custom deserializer for
NestedPojo
with your own parsing rules. For example