Android Gson:反序列化可以是单个对象或数组的对象
我使用Gson解析来自某个API的JSON响应。 一切正常,但现在似乎响应的一个字段可以是数组形式或单个元素形式,因此我得到了Android Gson:反序列化可以是单个对象或数组的对象,android,json,gson,Android,Json,Gson,我使用Gson解析来自某个API的JSON响应。 一切正常,但现在似乎响应的一个字段可以是数组形式或单个元素形式,因此我得到了com.google.gson.JsonSyntaxException:java.lang.IllegalStateException: 在这里,您可以看到导致问题的两个JSON版本的片段: 版本1 版本2 要分析版本1,我使用以下类: public类Notes实现了可序列化{ @序列化名称(“注释”) @暴露 私有列表注释=null; 公共列表getNote(){ 退货
com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:
在这里,您可以看到导致问题的两个JSON版本的片段:
版本1
版本2
要分析版本1,我使用以下类:
public类Notes实现了可序列化{
@序列化名称(“注释”)
@暴露
私有列表注释=null;
公共列表getNote(){
退货单;
}
公共无效设置注释(列表注释){
this.note=注释;
}
}
这适用于版本1,但当它发现JSON响应的一部分与版本2匹配时,它当然会给出:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT
我如何使其反序列化
注释
,无论它们有什么格式?您遇到的问题是GSON需要一个数组,但JSON是and对象的序列化
基本上,GSON需要“[”但找到了“{”
因此,您应该修改version2的代码,将JSON反序列化为单个Notes对象
此外,您还应该查看这两个JSON版本
根据GSON,您的版本2 JSON稍微无效
您有一个注释对象列表
必须表示为
“注”[注…]
这正是版本1中的内容
我建议将您的版本2 JSON更改为类似的版本
“注释”{
“注”:[
不管你有什么笔记
进去。
]
}
如果更改JSON不在您的权限之内,
然后考虑另一类类似的情况。
你应该用@SerializedNames和一个Note对象创建一个新类,然后用它来反序列化json。我想,这个问题属于最著名的Gson相关问题组之一,设计不当的json回答会造成伤害。你可以在这里找到确切的解决方案:。一旦你有了类型适配器工厂,你就可以注释你的如下所示的映射:
final class ResponseV1{
@序列化名称(“注释”)
最终注释Rapperv1注释=null;
}
final class NotesWrapperV1{
@序列化名称(“注释”)
@JsonAdapter(AlwaysListTypeAdapterFactory.class)
最终列表注释=空;
}
期末备忘{
最终字符串键=null;
最终字符串部分=null;
最终字符串优先级=null;
最终字符串消息=null;
}
在我看来,您可以进一步删除内部包装器类
final class ResponseV2{
@序列化名称(“注释”)
@JsonAdapter(NestedNotesTypeAdapterFactory.class)
最终列表注释=空;
}
其中NestedNotesTypeAdapterFactory
的实现方式如下:
最终类NestedNotesTypeAdapterFactory
实现TypeAdapterFactory{
私有静态最终类型令牌noteListTypeToken=新类型令牌(){
};
私有NestedNotesTypeAdapterFactory(){
}
@凌驾
公共类型适配器创建(最终Gson Gson、最终TypeToken TypeToken){
//只需将factory方法添加到AlwaysListTypeAdapterFactory,并让它只返回singleton类(工厂是无状态的,因此可以构造一次)
最终类型适配器noteListTypeAdapter=getAlwaysListTypeAdapterFactory().create(gson,noteListTypeToken);
最终类型适配器nestedNotesTypeAdapter=新nestedNotesTypeAdapter(noteListTypeAdapter);
@抑制警告(“未选中”)
最终类型适配器TypeAdapter=(TypeAdapter)nestedNotesTypeAdapter;
返回类型适配器;
}
私有静态最终类NestedNotesTypeAdapter
扩展类型适配器{
私有最终类型适配器noteListTypeAdapter;
专用NestedNotesTypeAdapter(最终类型适配器noteListTypeAdapter){
this.noteListTypeAdapter=noteListTypeAdapter;
}
@凌驾
公共无效写入(最终JsonWriter out,最终列表值){
抛出新的UnsupportedOperationException();
}
@凌驾
已读取公共列表(中的最终JsonReader)
抛出IOException{
//在此处“展开”注释属性
in.beginObject();
列表注释=空;
while(在.hasNext()中){
最终字符串名称=in.nextName();
交换机(名称){
案例“注”:
//如果我们已经到达Note属性,请阅读列表
notes=noteListTypeAdapter.read(在中);
打破
违约:
抛出新的MalformedJsonException(“无法识别的”+name+”位于“+in”);
}
}
in.endObject();
回条;
}
}
}
两种实现的测试用例:
for(最终字符串资源:ImmutableList.of(“version-1.json”、“version-2.json”)){
System.out.println(资源);
try(final-JsonReader-JsonReader=getPackageResourceJsonReader(Q43868120.class,resource)){
final ResponseV1 response=gson.fromJson(jsonReader,ResponseV1.class);
用于(最终注释:response.notes.notes){
System.out.println(note.message);
}
}
}
for(最终字符串资源:ImmutableList.of(“version-1.json”、“version-2.json”)){
System.out.println(资源);
try(final-JsonReader-JsonReader=getPackageResourceJsonReader(Q43868120.class,resource)){
final ResponseV2 response=gson.fromJson(jsonReader,ResponseV2.class);
用于(最终注释:response.notes){
System.out.println(note.message);
}
}
}
两者都产生以下结果:<
{
"Notes": {
"Note": {
"key": "medium",
"section": "low",
"priority": "1",
"message": "Life time for the battery will expire soon"
}
}
}
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT