प्रति क्षेत्र में कई GSON @SerializedName?


104

क्या किसी प्रकार का JSON फ़ील्ड्स को एकल Java ऑब्जेक्ट सदस्य चर में मैप करने के लिए Gson में कोई तरीका है?

मान लीजिए कि मेरे पास जावा क्लास है ...

public class MyClass {
    String id;
    String name;
}

मैं दो अलग-अलग सेवाओं के साथ इस एकल वर्ग का उपयोग करना चाहता हूं। हालाँकि, ये दोनों सेवाएँ भिन्न हैं कि वे अपना डेटा कैसे लौटाते हैं ...

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

... तथा ...

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

... क्रमशः।

क्या जावा ऑब्जेक्ट में फ़ील्ड में JSON स्ट्रिंग में फ़ील्ड "person"और "user"फ़ील्ड दोनों को मैप करने का कोई तरीका है name?

(नोट: मुझे केवल JSON स्ट्रिंग से जावा ऑब्जेक्ट में बदलने की आवश्यकता है - कभी भी अन्य तरीके से नहीं।


1
यहाँ सरल और सही स्पष्टीकरण है। भविष्यवाणियां .io
अतुल भारद्वाज

जवाबों:


239

अक्टूबर 2015 में, जीसन संस्करण 2.4 ( चैंज ) ने डिसेरराइजिंग करते समय वैकल्पिक / कई नामों का उपयोग करने की क्षमता को जोड़ा @SerializedName। कोई और अधिक कस्टम टाइप एडेप्टर की जरूरत है!

उपयोग:

@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
यहाँ सरल और बिल्कुल सही व्याख्या है futurestud.io/tutorials/...
अतुल भारद्वाज

गजब का! इस उत्तर के लिए धन्यवाद!
सूर्यलोक 3

महान जवाब, धन्यवाद!
डोर रुड

27

यह @SerializedNameGson में एक क्षेत्र में कई एनोटेशन को परिभाषित करने के लिए समर्थित नहीं है ।

कारण: डिफ़ॉल्ट रूप से Deserialization को एक LinkedHashMap के साथ प्रबंधित किया जाता है और इनकमिंग आने वाले जॉन्स फ़ील्ड नाम (कस्टम क्लास के फ़ील्ड नाम या क्रमबद्ध नाम नहीं) द्वारा परिभाषित किए जाते हैं और एक से एक मैपिंग होती है। आप ReflectiveTypeAdapterFactoryकक्षा की आंतरिक कक्षा Adapter<T>की read(JsonReader in)विधि में कार्यान्वयन (कैसे deserialization काम करता है) देख सकते हैं ।

समाधान: आप एक कस्टम लिख सकते हैं TypeAdapter जो हैंडल name, personऔर userjson टैग और उन्हें अपने कस्टम वर्ग का नाम क्षेत्र के लिए नक्शे 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();
    }
}

परीक्षण का मामला:

    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 के बारे में उदाहरण।

संपादित करें 2016.04.06: जैसा कि @Mathieu Castets ने अपने उत्तर में लिखा है, यह अब समर्थित है। (यह इस प्रश्न का सही उत्तर है।)

सार्वजनिक अमूर्त स्ट्रिंग [] वैकल्पिक
रिटर्न: फ़ील्ड का वैकल्पिक नाम जब यह डीरिशियल
डिफॉल्ट होता है: {}


यहाँ सरल और बिल्कुल सही व्याख्या है futurestud.io/tutorials/...
अतुल भारद्वाज


8

KOTLIN के लिए मैंने नीचे इस्तेमाल किया लेकिन काम नहीं करता है

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

इसलिए मैंने इसे संपादित किया और यहाँ यह ठीक काम करता है !!

@SerializedName(value="name", alternate= arrayOf("person", "user"))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.