ספר בישול של התנערות Gson

בספר בישול זה אנו בוחנים את הדרכים השונות לפרק את JSON לאובייקטים של Java, באמצעות ספריית Gson הפופולרית.

1. התאם את JSON לאובייקט בסיסי יחיד

נתחיל בפשטות - אנחנו הולכים לבטל מרס של json פשוט לאובייקט Java - פו:

כיתה ציבורית Foo {public int intalue; מחרוזת מחרוזת ציבורית; // + שווה ויישומי hashCode}

והפתרון:

@Test הציבור בטל כאשרDererializingToSimpleObject_thenCorrect () {String json = "{" intValue ": 1," stringValue ":" one "}"; Foo targetObject = Gson חדש (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "one"); }

2. התאם את JSON לאובייקט כללי

הבא - בואו נגדיר אובייקט באמצעות גנריות:

מעמד ציבורי GenericFoo {public T theValue; }

ופירוש כמה ג'ונסונים לסוג האובייקט הזה:

@Test ציבורי בטל כאשרDeserializingToGenericObject_thenCorrect () {Type typeToken = TypeToken חדש() {} .getType (); מחרוזת json = "{" theValue ": 1}"; GenericFoo targetObject = Gson חדש (). FromJson (json, typeToken); assertEquals (targetObject.theValue, מספר שלם חדש (1)); }

3. התפטל מחדש מה JSON עם שדות לא ידועים נוספים להתנגדות

לאחר מכן - בואו לבטל את ערעור ה- json המורכב שמכיל תוספות נוספות, שדות לא ידועים:

@ מבחן חלל ציבורי שניתן JsonHasExtraValues_whenDeserializing_thenCorrect () {String json = "{" intValue ": 1," stringValue ":" one "," extraString ":" two "," extraFloat ": 2.2}"; Foo targetObject = Gson חדש (). מאת Json (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "one"); }

כפי שאתה יכול לראות, Gson יתעלם מהשדות הלא ידועים ופשוט להתאים את השדות שהוא מסוגל.

4. בטל את התיעוד של JSON עם שמות שדות שאינם תואמים להתנגדות

עכשיו, בואו נראה איך Gson עושה עם מחרוזת json המכילה שדות שפשוט לא תואמים את השדות שלנו פו לְהִתְנַגֵד:

@ מבחן חלל ציבורי שניתן JsonHasNonMatchingFields_whenDeserializingWithCustomDeserializer_thenCorrect () {String json = "{" valueInt ": 7," valueString ":" שבע "}"; GsonBuilder gsonBldr = GsonBuilder חדש (); gsonBldr.registerTypeAdapter (Foo.class, FooDeserializer חדשFromJsonWithDifferentFields ()); Foo targetObject = gsonBldr.create (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 7); assertEquals (targetObject.stringValue, "שבע"); }

שימו לב שנרשמנו deserializer מותאם אישית - זה היה מסוגל לנתח נכון את השדות ממחרוזת json ולמפות אותם אל שלנו פו:

מחלקה ציבורית FooDeserializerFromJsonWithDifferentFields מיישמת JsonDeserializer {@Override ציבורית Foo deserialize (JsonElement jElement, Type typeOfT, JsonDeserializationContext context) זורק JsonParseException {JsonObject jObject = jElementOget. int intValue = jObject.get ("valueInt"). getAsInt (); מחרוזת stringValue = jObject.get ("valueString"). GetAsString (); להחזיר Foo חדש (intValue, stringValue); }}

5. התאם מערך JSON למערך אובייקטים של Java

לאחר מכן, אנו הולכים לבטל את הערעור מערך json למערך ג'אווה שֶׁל פו חפצים:

@Test public void givenJsonArrayOfFoos_whenDeserializingToArray_thenCorrect () {String json = "[{" intValue ": 1," stringValue ":" one "}," + "{" intValue ": 2," stringValue ":" two "}]"; Foo [] targetArray = GsonBuilder חדש (). Create (). FromJson (json, Foo []. Class); assertThat (Lists.newArrayList (targetArray), hasItem (Foo חדש (1, "אחד"))); assertThat (Lists.newArrayList (targetArray), hasItem (Foo חדש (2, "שניים"))); assertThat (Lists.newArrayList (targetArray), not (hasItem (Foo חדש (1, "שניים")))); }

6. התפטלו מחדש מהאוסף JSON Array to Java

לאחר מכן, מערך json ישירות לאוסף Java:

@Test public void givenJsonArrayOfFoos_whenDeserializingCollection_thenCorrect () {String json = "[{" intValue ": 1," stringValue ":" one "}, {" intValue ": 2," stringValue ":" two "}]"; הקלד targetClassType = TypeToken חדש() {} .getType (); אוסף targetCollection = Gson חדש (). FromJson (json, targetClassType); assertThat (targetCollection, instanceOf (ArrayList.class)); }

7. בטל את התיעוד של JSON לאובייקטים מקוננים

לאחר מכן, בואו נגדיר את האובייקט המקונן שלנו - FooWithInner:

כיתה ציבורית FooWithInner {public int intalue; מחרוזת מחרוזת ציבורית; ציבורי InnerFoo innerFoo; מחלקה ציבורית InnerFoo {שם מחרוזת ציבורי; }}

והנה כיצד לבטל עריכה מחדש של קלט המכיל אובייקט מקונן זה:

@ מבחן ציבורי בטל כאשרDeserializingToNestedObjects_thenCorrect () {String json = "{\" intValue \ ": 1, \" stringValue \ ": \" one \ ", \" innerFoo \ ": {\" name \ ": \" inner \ "}}"; FooWithInner targetObject = Gson חדש (). מאת Json (json, FooWithInner.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "one"); assertEquals (targetObject.innerFoo.name, "פנימי"); }

8. התפטל מחדש מה JSON באמצעות קונסטרוקטור מותאם אישית

לבסוף, בואו נראה כיצד לאלץ שימוש בבנאי ספציפי במהלך עריכת ערוצים במקום ברירת מחדל - אין בונה ארגומנטים - באמצעות InstanceCreator:

מחלקה ציבורית FooInstanceCreator מיישמת את InstanceCreator {@Override Public Foo createInstance (Type type) {להחזיר Foo חדש ("מדגם"); }}

והנה כיצד להשתמש שלנו FooInstanceCreator בהתנערות:

@ מבחן ציבורי בטל כאשר DeserializingUsingInstanceCreator_thenCorrect () {String json = "{\" intValue \ ": 1}"; GsonBuilder gsonBldr = GsonBuilder חדש (); gsonBldr.registerTypeAdapter (Foo.class, FooInstanceCreator חדש ()); Foo targetObject = gsonBldr.create (). FromJson (json, Foo.class); assertEquals (targetObject.intValue, 1); assertEquals (targetObject.stringValue, "מדגם"); }

שים לב שבמקום null, ה- Foo.stringValue שווים לִטעוֹם כאשר השתמשנו בבנאי הבא:

Foo פומבי (String stringValue) {this.stringValue = stringValue; }

9. מסקנה

מאמרים אלה מראים כיצד למנף את ספריית Gson לנתח את קלט JSON - לעבור על מקרי השימוש הנפוצים ביותר עבור אובייקטים בודדים וגם מרובים.

יישום כל הדוגמאות וקטעי הקוד ניתן למצוא בפרויקט github שלי - זהו פרויקט מבוסס ליקוי חמה, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.


$config[zx-auto] not found$config[zx-overlay] not found