Alan başına birden çok GSON @SerializedName?


105

Gson'da birden çok JSON alanını tek bir Java nesne üye değişkeniyle eşlemenin herhangi bir yolu var mı?

Diyelim ki bir Java dersim var ...

public class MyClass {
    String id;
    String name;
}

Bu tek sınıfı iki farklı hizmetle kullanmak istiyorum. Ancak, bu iki hizmet verilerini nasıl iade ettiklerine göre farklılık gösterir ...

{ "id": 2341, "person": "Bob" }

... ve ...

{ "id": 5382, "user": "Mary" }

... sırasıyla.

JSON dizesindeki "person"ve "user"alanlarını nameJava nesnesindeki alanla eşlemenin herhangi bir yolu var mı ?

(Not: Sadece JSON dizesini Java nesnesine dönüştürmem gerekiyor - asla tersi olmaz.)


1
İşte basit ve Mükemmel açıklama futurestud.io/tutorials/…
Atul Bhardwaj

Yanıtlar:


242

Ekim 2015'te, Gson sürüm 2.4 ( değişiklik günlüğü) seriyi kaldırırken alternatif / birden çok ad kullanma özelliğini ekledi @SerializedName. Artık özel TypeAdapter gerekmez!

Kullanım:

@SerializedName(value="name", alternate={"person", "user"})

https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/annotations/SerializedName.html


1
İşte basit ve Mükemmel açıklama futurestud.io/tutorials/…
Atul Bhardwaj

İnanılmaz! Bu cevap için teşekkürler!
sunlover3

27

@SerializedNameGson'daki bir alana birden çok ek açıklama tanımlamak desteklenmez .

Sebep: Varsayılan olarak seriyi kaldırma bir LinkedHashMap ile yönetilir ve anahtarlar gelen json's alan adlarıyla tanımlanır (özel sınıfın alan adları veya serileştirilmiş Adlar değil) ve bire bir eşleme vardır. En uygulanmasını (nasıl seri kaldırma işleri) görebilirsiniz ReflectiveTypeAdapterFactorysınıfının iç sınıf Adapter<T>'ın read(JsonReader in)yöntemiyle.

Çözüm: Özel bir yazabilirsiniz TypeAdapter hangi kolları name, personve userjson etiketleri ve özel sınıfın adı alanına onları eşler 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();
    }
}

Test durumu:

    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"}

TypeAdapters ile ilgili örnekler.

Edit 2016.04.06: @Mathieu Castets'in cevabında yazdığı gibi, şu anda destekleniyor. (Bu soru için doğru cevap budur.)

public abstract String [] alternate
İade: serileştirme kaldırıldığında alanın alternatif adları
Varsayılan: {}


İşte basit ve Mükemmel açıklama futurestud.io/tutorials/…
Atul Bhardwaj

20

için Kotlin fanlar

@SerializedName(value="name", alternate= ["person", "user"])

8

KOTLIN için aşağıda kullandım ama çalışmıyor

@SerializedName(value="name", alternate= ["person", "user"])

bu yüzden düzenledim ve burada iyi çalışıyor!

@SerializedName(value="name", alternate= arrayOf("person", "user"))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.