Tidak didukung untuk menentukan beberapa @SerializedName
anotasi ke bidang di Gson.
Alasan: Secara default Deserialization dikelola dengan LinkedHashMap dan kuncinya ditentukan oleh nama field json yang masuk (bukan nama field kelas kustom atau serializedNames) dan ada pemetaan satu lawan satu. Anda dapat melihat pelaksanaan (bagaimana deserialization bekerja) di ReflectiveTypeAdapterFactory
kelas batin kelas ini Adapter<T>
's read(JsonReader in)
metode.
Solusi:
Anda dapat menulis TypeAdapter khusus yang menangani name
, person
dan user
tag json dan memetakannya ke bidang nama kelas khusus Anda MyClass
:
class MyClassTypeAdapter extends TypeAdapter<MyClass> {
@Override
public MyClass read(final JsonReader in) throws IOException {
final MyClass myClassInstance = new MyClass();
in.beginObject();
while (in.hasNext()) {
String jsonTag = in.nextName();
if ("id".equals(jsonTag)) {
myClassInstance.id = in.nextInt();
} else if ("name".equals(jsonTag)
|| "person".equals(jsonTag)
|| "user".equals(jsonTag)) {
myClassInstance.name = in.nextString();
}
}
in.endObject();
return myClassInstance;
}
@Override
public void write(final JsonWriter out, final MyClass myClassInstance)
throws IOException {
out.beginObject();
out.name("id").value(myClassInstance.id);
out.name("name").value(myClassInstance.name);
out.endObject();
}
}
Kasus cobaan:
String jsonVal0 = "{\"id\": 5382, \"user\": \"Mary\" }";
String jsonVal1 = "{\"id\": 2341, \"person\": \"Bob\"}";
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassTypeAdapter());
final Gson gson = gsonBuilder.create();
MyClass myClassInstance0 = gson.fromJson(jsonVal0, MyClass.class);
MyClass myClassInstance1 = gson.fromJson(jsonVal1, MyClass.class);
System.out.println("jsonVal0 :" + gson.toJson(myClassInstance0));
// output: jsonVal0 :{"id":5382,"name":"Mary"}
System.out.println("jsonVal1 :" + gson.toJson(myClassInstance1));
// output: jsonVal1 :{"id":2341,"name":"Bob"}
Contoh tentang TypeAdapters.
Sunting 2016.04.06: Seperti yang ditulis oleh @Mathieu Castets pada jawabannya, sekarang ini didukung. (Itu adalah jawaban yang benar untuk pertanyaan ini.)
public abstract String [] alternate
Returns: nama alternatif dari bidang ketika deserialisasi
Default: {}