这个问题属于最著名的Gson相关问题组之一,我猜测,不当设计的JSON响应会对其造成伤害。你可以在这里找到确切的解决方案:让GSON接受期望数组的单个对象。一旦你拥有了该类型适配器工厂,你就可以像这样注释你的映射:
final class ResponseV1 {
@SerializedName("Notes")
final NotesWrapperV1 notes = null;
}
final class NotesWrapperV1 {
@SerializedName("Note")
@JsonAdapter(AlwaysListTypeAdapterFactory.class)
final List<Note> notes = null;
}
final class Note {
final String key = null;
final String section = null;
final String priority = null;
final String message = null;
}
我认为,你甚至可以进一步移除内部包装类。
final class ResponseV2 {
@SerializedName("Notes")
@JsonAdapter(NestedNotesTypeAdapterFactory.class)
final List<Note> notes = null;
}
NestedNotesTypeAdapterFactory
是这样实现的:
final class NestedNotesTypeAdapterFactory
implements TypeAdapterFactory {
private static final TypeToken<List<Note>> noteListTypeToken = new TypeToken<List<Note>>() {
};
private NestedNotesTypeAdapterFactory() {
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
final TypeAdapter<List<Note>> noteListTypeAdapter = getAlwaysListTypeAdapterFactory().create(gson, noteListTypeToken);
final TypeAdapter<List<Note>> nestedNotesTypeAdapter = new NestedNotesTypeAdapter(noteListTypeAdapter);
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) nestedNotesTypeAdapter;
return typeAdapter;
}
private static final class NestedNotesTypeAdapter
extends TypeAdapter<List<Note>> {
private final TypeAdapter<List<Note>> noteListTypeAdapter;
private NestedNotesTypeAdapter(final TypeAdapter<List<Note>> noteListTypeAdapter) {
this.noteListTypeAdapter = noteListTypeAdapter;
}
@Override
public void write(final JsonWriter out, final List<Note> value) {
throw new UnsupportedOperationException();
}
@Override
public List<Note> read(final JsonReader in)
throws IOException {
in.beginObject();
List<Note> notes = null;
while ( in.hasNext() ) {
final String name = in.nextName();
switch ( name ) {
case "Note":
notes = noteListTypeAdapter.read(in);
break;
default:
throw new MalformedJsonException("Unrecognized " + name + " at " + in);
}
}
in.endObject();
return notes;
}
}
}
两种实现的测试用例:
for ( final String resource : ImmutableList.of("version-1.json", "version-2.json") ) {
System.out.println(resource);
try ( final JsonReader jsonReader = getPackageResourceJsonReader(Q43868120.class, resource) ) {
final ResponseV1 response = gson.fromJson(jsonReader, ResponseV1.class);
for ( final Note note : response.notes.notes ) {
System.out.println(note.message);
}
}
}
for ( final String resource : ImmutableList.of("version-1.json", "version-2.json") ) {
System.out.println(resource);
try ( final JsonReader jsonReader = getPackageResourceJsonReader(Q43868120.class, resource) ) {
final ResponseV2 response = gson.fromJson(jsonReader, ResponseV2.class);
for ( final Note note : response.notes ) {
System.out.println(note.message);
}
}
}
两者都会生成以下内容:
version-1.json
电池消耗突然增加。
转换器的功率可能过高。
version-2.json
电池寿命即将到期。