Pracuję nad app, który używa GSON jako json Deserializatora i musi deserializowania polimorficzny json z REST API. Zanim wyjaśniam mi, proszę zauważyć, że już szukałem polimorficznej deserializacji z GSONem i wdrożyłem ją w kilku przypadkach z powodzeniem. To jest specyficzny problem, który mam. Przeczytałem też this great post i this stackoverflow discussion zanim się o to zapytam. Używam RuntimeTypeAdapterFactory do deserializacji obiektów polimorficznych przy okazji.deserializacji polimorficzny JSON z GSON rzuca wyjątek
Problem polega na tym, że GSON RuntimeTypeAdapterFactory nie pozwala zadeklarować pola, które określa typ obiektu wewnątrz struktury hierarchii. Wyjaśnię dalej za pomocą kodu. Mam następującą strukturę POJOs (POJOs została zredukowana do uproszczenia):
public abstract class BaseUser {
@Expose
protected EnumMobileUserType userType;
}
public class User extends BaseUser {
@Expose
private String name;
@Expose
private String email;
}
public class RegularUser extends User {
@Expose
private String address;
}
public class SpecialUser extends User {
@Expose
private String promoCode;
}
Teraz jest to kod gdzie zdefiniował runtimeTypeAdapterFactory dla hierarchii Użytkownika.
public static RuntimeTypeAdapterFactory<BaseUser> getUserTypeAdapter() {
return RuntimeTypeAdapterFactory
.of(BaseUser.class, "userType")
.registerSubtype(User.class, EnumMobileUserType.USER.toString())
.registerSubtype(RegularUser.class, EnumMobileUserType.REGULAR.toString())
.registerSubtype(SpecialUser.class, EnumMobileUserType.SPECIAL.toString());
}
public static Gson getGsonWithTypeAdapters() {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapterFactory(getUserTypeAdapter());
return builder.create();
}
Teraz, gdy próbuję deserializować JSON:
{
"user":{
"userType":"USER",
"email":"[email protected]",
"name":"Albert"
}
}
otrzymuję ten wyjątek
com.google.gson.JsonParseException: cannot serialize com.mobile.model.entities.v2.common.User because it already defines a field named userType
Ale jeśli zmienić nazwę właściwości "UserType" w mojej klasie BaseUser na przykład "typ" i deserializuję to samo poprawnie. Nie rozumiem, dlaczego GSON runtimTypeAdapterFactory ma to ograniczenie. W rzeczywistości w this blog post najwyraźniej nie jest to problemem.
Może ktoś wyjaśnić, co tu się dzieje, dlaczego nazwa obiektu, który określa typ nie może być zdefiniowana wewnątrz hierarchii POJOs?
EDYCJA Problem nie występuje podczas deserializacji, ale w przypadku serializacji za pomocą kodu opisanego powyżej. Znajdź dodatkowe wyjaśnienie w odpowiedzi.
Zgodnie z błędu, to na pewno nie zadeklarowały pole 'userType' w' użytkownik portu klasa też? Jest już zadeklarowany w klasie "BaseUser", więc nie trzeba go redeclare. –
Witaj Jyotman. Nie, upewniłem się, że nie zadeklarowałem dwa razy wartości usertype pola. Jest zadeklarowany tylko dla użytkownika podstawowego.Plus powiedziałem na końcu pytania, deserializacja działa dobrze, gdy tylko zmieni nazwę pola userType z klasy BaseUser na coś innego niż to, co jest zadeklarowane w json i RuntimeTypeAdapterFactory. Ale dzięki za sugestię! – JorgeMuci