(这篇文章是一个规范性的问题,下面提供了一个示例答案.)
我正在尝试将一些JSON内容反序列化为自定义POJO类型Gson#fromJson(String, Class).
这段代码
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;
}
Run Code Online (Sandbox Code Playgroud)
抛出以下异常
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
Run Code Online (Sandbox Code Playgroud)
为什么Gson不能正确地将我的JSON文本转换为我的POJO类型?
Sot*_*lis 31
正如异常消息所述
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
Run Code Online (Sandbox Code Playgroud)
反序列化时,Gson期待一个JSON对象,但找到了一个JSON数组.由于它无法从一个转换为另一个,它抛出了这个异常.
这里描述了 JSON格式.简而言之,它定义了以下类型:对象,数组,字符串,数字null,以及布尔值true和false.
在Gson(以及大多数JSON解析器)中,存在以下映射:JSON字符串映射到Java String; JSON号映射到Java Number类型; JSON数组映射到Collection类型或数组类型; JSON对象映射到Java Map类型,或者通常是自定义POJO类型(之前未提及); null映射到Java null,布尔值映射到Java true和false.
Gson迭代您提供的JSON内容,并尝试将其反序列化为您请求的相应类型.如果内容不匹配或无法转换为预期类型,则会抛出相应的异常.
在您的情况下,您提供了以下JSON
{
"nestedPojo": [
{
"name": null,
"value": 42
}
]
}
Run Code Online (Sandbox Code Playgroud)
在根目录下,这是一个JSON对象,其中包含一个名为nestedPojoJSON数组的成员.该JSON数组包含单个元素,另一个JSON对象包含两个成员.考虑到前面定义的映射,您希望此JSON映射到Java对象,该对象具有一个名为nestedPojosome Collection或array type 的字段,其中该类型分别定义了两个名为nameand的字段value.
但是,您已将Pojo类型定义为具有字段
NestedPojo nestedPojo;
Run Code Online (Sandbox Code Playgroud)
既不是数组类型,也不是Collection类型.Gson无法反序列化此字段的相应JSON.
相反,您有3个选择:
更改您的JSON以匹配预期的类型
{
"nestedPojo": {
"name": null,
"value": 42
}
}
Run Code Online (Sandbox Code Playgroud)更改您的Pojo类型以期望a Collection或数组类型
List<NestedPojo> nestedPojo; // consider changing the name and using @SerializedName
NestedPojo[] nestedPojo;
Run Code Online (Sandbox Code Playgroud)NestedPojo使用您自己的解析规则编写并注册自定义反序列化器.例如
class Custom implements JsonDeserializer<NestedPojo> {
@Override
public NestedPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
NestedPojo nestedPojo = new NestedPojo();
JsonArray jsonArray = json.getAsJsonArray();
if (jsonArray.size() != 1) {
throw new IllegalStateException("unexpected json");
}
JsonObject jsonObject = jsonArray.get(0).getAsJsonObject(); // get only element
JsonElement jsonElement = jsonObject.get("name");
if (!jsonElement.isJsonNull()) {
nestedPojo.name = jsonElement.getAsString();
}
nestedPojo.value = jsonObject.get("value").getAsInt();
return nestedPojo;
}
}
Gson gson = new GsonBuilder().registerTypeAdapter(NestedPojo.class, new Custom()).create();
Run Code Online (Sandbox Code Playgroud)class Pojo {
NestedPojo nestedPojo;
}
Run Code Online (Sandbox Code Playgroud)
在你的json中你有一个nestedPojo数组,所以你要么改变代码
NestedPojo[] nestedPojo;
Run Code Online (Sandbox Code Playgroud)
或者你改变了json字符串
String json = "{\"nestedPojo\":{\"name\":null, \"value\":42}}";
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38653 次 |
| 最近记录: |