המרת JSON למפה באמצעות Gson

1. הקדמה

במדריך מהיר זה נלמד כיצד להמיר מחרוזת JSON ל- מַפָּה באמצעות גסון מגוגל.

נראה שלוש גישות שונות כדי להשיג זאת ולדון ביתרונות ובחסרונות שלהן - עם כמה דוגמאות מעשיות.

2. עוברים Map.class

בכללי, Gson מספק את ה- API הבא שלה גסון בכיתה להמרת מחרוזת JSON לאובייקט:

T מ- Json (מחרוזת json, Class classOfT) זורק את JsonSyntaxException;

מהחתימה, ברור מאוד שהפרמטר השני הוא המחלקה של האובייקט שאליו אנו מתכוונים לנתח את JSON. במקרה שלנו, זה צריך להיות Map.class:

מחרוזת jsonString = "{'עובד.שם': 'בוב', 'עובד.שכר': 10000}"; Gson gson = Gson חדש (); מפת מפה = gson.fromJson (jsonString, Map.class); Assert.assertEquals (2, map.size ()); Assert.assertEquals (Double.class, map.get ("עובד.שכר"). GetClass ());

גישה זו תנחש את המיטב לגבי סוג הערך עבור כל נכס.

לדוגמה, מספרים יכופפו לְהַכפִּילs, נָכוֹן ו שֶׁקֶר לְתוֹך בוליאני, וחפצים לתוך LinkedTreeMapס.

אם יש מפתחות כפולים, הכפייה תיכשל והיא תזרוק JsonSyntaxException.

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

3. שימוש TypeToken

כדי להתגבר על בעיית מחיקת הסוגים עבור הסוגים הגנריים, גסון יש גרסה עמוסה יותר של ה- API:

ציבורי T fromJson (מחרוזת json, Type typeOfT) זורק JsonSyntaxException;

אנחנו יכולים לבנות א מַפָּה עם פרמטרי הסוג שלו באמצעות Gson's TypeToken. ה TypeToken מחלקה מחזירה מופע של ParameterizedTypeImpl השומר על סוג המפתח והערך גם בזמן הריצה:

String jsonString = "{'Bob': {'name': 'Bob Willis'}," + "'Jenny': {'name': 'Jenny McCarthy'}," + "'Steve': {'name': 'סטיבן וו'}} "; Gson gson = Gson חדש (); הקלד empMapType = TypeToken חדש() {} .getType (); שם מפהEmployeeMap = gson.fromJson (jsonString, empMapType); Assert.assertEquals (3, nameEmployeeMap.size ()); Assert.assertEquals (Employee.class, nameEmployeeMap.get ("Bob"). GetClass ()); 

עכשיו, אם נבנה את שלנו מַפָּה הקלד כמו מַפָּה, אז המנתח עדיין יוגדר כברירת מחדל כפי שראינו בסעיף הקודם.

כמובן, זה עדיין נופל חזרה לגסון בגין כפיית טיפוסים פרימיטיביים. עם זאת, ניתן להתאים גם את אלה.

4. שימוש בהתאמה אישית JsonDeserializer

כאשר אנו זקוקים לשליטה דקה על בניית שלנו מַפָּה אובייקט, אנו יכולים ליישם deserializer מותאם אישית מסוג JsonDeserializer.

כדי לראות דוגמה, נניח ש- JSON שלנו מכיל את שם העובד כמפתח ותאריך שכירתו כערכו. יתר על כן, נניח שהתבנית של התאריך היא yyyy / MM / dd, שאינו פורמט סטנדרטי עבור גסון.

אנו יכולים להגדיר את Gson לנתח את המפה שלנו בצורה שונה, ואז, על ידי יישום a JsonDeserializer:

בכיתה ציבורית StringDateMapDeserializer מיישם את JsonDeserializer {פורמט SimpleDateFormat פרטי = SimpleDateFormat חדש ("yyyy / MM / dd"); @ ביטול המפה הציבורית מבטל את העריכה מחדש (JsonElement elem, סוג סוג, JsonDeserializationContext jsonDeserializationContext) {return elem.getAsJsonObject () .entrySet () .stream () .filter (e -> e.getValue (). IsJsonPrimitive ()). -> e.getValue (). getAsJsonPrimitive (). isString ()) .collect (Collectors.toMap (Map.Entry :: getKey, e -> formatDate (e.getValue ()))); } פורמט תאריך פרטי Date (ערך אובייקט) {try {return format (value.getAsString ()); } לתפוס (ParseException לשעבר) {לזרוק JsonParseException חדש (לשעבר); }}} 

עכשיו, עלינו לרשום את זה ב GsonBuilder נגד סוג היעד שלנו מַפָּה> ולבנות אישית גסון לְהִתְנַגֵד.

כשאנחנו קוראים מג'ייסון ממשק API בנושא זה גסון האובייקט, המנתח מזמין את deserializer המותאם אישית ומחזיר את הרצוי מַפָּה למשל:

מחרוזת jsonString = "{'בוב': '2017-06-01', 'ג'ני': '2015-01-03'}"; סוג סוג = סוג חדש() {}. getType (); Gson gson = GsonBuilder חדש () .registerTypeAdapter (סוג, חדש StringDateMapDeserializer ()) .create (); מפה empJoiningDateMap = gson.fromJson (jsonString, סוג); Assert.assertEquals (2, empJoiningDateMap.size ()); Assert.assertEquals (Date.class, empJoiningDateMap.get ("Bob"). GetClass ()); 

טקטיקה זו שימושית גם כאשר המפה שלנו עשויה להכיל ערכים הטרוגניים ויש לנו מושג הוגן כמה סוגים שונים של ערכים יכולים להיות שם.

למידע נוסף אודות מכשיר deserializer מותאם אישית ב גסון, אתם מוזמנים לעבור על ספר הבישול של Dessonialization של Gson.

5. מסקנה

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

קוד המקור של הדוגמאות זמין ב- GitHub.


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