כיצד לערוך סדר ולהפוך ערוצים עם ג'קסון

1. סקירה כללית

מדריך מהיר זה יראה כיצד לשלוט בדרך Java Enums מסודרים ומוערכים עם ג'קסון 2.

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

2. שליטה בייצוג Enum

בואו נגדיר את Enum הבא:

מרחק ציבורי מרחק {KILOMETER ("km", 1000), MILE ("miles", 1609.34), METER ("meters", 1), INCH ("inches", 0.0254), CENTIMETER ("cm", 0.01), MILLIMETER ("מ"מ", 0.001); יחידת מיתרים פרטית; מטר כפול אחרון פרטי; מרחק פרטי (יחידת מחרוזת, מטר כפול) {this.unit = יחידה; this.meters = מטרים; } // גטרים וקובעים סטנדרטיים}

3. סדר סדרת Enums ל- JSON

3.1. ייצוג ברירת מחדל של Enum

כברירת מחדל, ג'קסון יציג את Java Enums כמחרוזת פשוטה - לדוגמא:

ObjectMapper חדש (). writeValueAsString (Distance.MILE);

יביא:

"מִיל"

מה נרצה לקבל כשמארשלים את זה Enum לאובייקט JSON זה לתת משהו כמו:

{"unit": "miles", "meters": 1609.34} 

3.2. Enum כאובייקט JSON

החל מג'קסון 2.1.2, קיימת כעת אפשרות תצורה שיכולה להתמודד עם ייצוג מסוג זה. ניתן לעשות זאת באמצעות @JsonFormat ביאור ברמת הכיתה:

@JsonFormat (צורה = JsonFormat.Shape.OBJECT) מרחק ציבורי מרחק {...}

זה יוביל לתוצאה הרצויה בעת סדרת זה enum ל מֶרְחָק.מִיל:

{"unit": "miles", "meters": 1609.34}

3.3. Enums ו @JsonValue

דרך נוספת ופשוטה יותר לשלוט על תפוקת המרשלים עבור אנומה היא שימוש ב- @JsonValue ביאור על גטר:

מרחק ציבורי מרחק {... @JsonValue מחרוזת ציבורית getMeters () {מטרים חוזרים; }}

מה שאנחנו מבטאים כאן זה getMeters () הוא הייצוג האמיתי של האומה הזו. אז התוצאה של סדרת סדר תהיה:

1609.34

3.4. Serializer מותאם אישית עבור Enum

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

מחלקה ציבורית DistanceSerializer מרחיב את StdSerializer {public DistanceSerializer () {super (Distance.class); } DistanceSerializer ציבורי (Class t) {super (t); } סידור חלל ציבורי (מרחק מרחק, מחולל JsonGenerator, ספק SerializerProvider) זורק IOException, JsonProcessingException {generator.writeStartObject (); generator.writeFieldName ("שם"); generator.writeString (distance.name ()); generator.writeFieldName ("יחידה"); generator.writeString (distance.getUnit ()); generator.writeFieldName ("מטרים"); generator.writeNumber (distance.getMeters ()); generator.writeEndObject (); }}

כעת ניישם את הסידורי על הכיתה שתסדר:

@JsonSerialize (באמצעות = DistanceSerializer.class) ציבור ציבורי TypeEnum {...}

מה שמביא ל:

{"name": "MILE", "unit": "miles", "meters": 1609.34}

4. התפטרות JSON ל- Enum

ראשית, נגדיר א עִיר כיתה שיש לה מֶרְחָק חבר:

מעמד ציבורי עיר {פרטי מרחק מרחק; ...}

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

4.1. התנהגות ברירת מחדל

כברירת מחדל, ג'קסון ישתמש בשם Enum כדי לבטל את הרישום מ- JSON.

לדוגמה, זה ינתק את הערכת ה- JSON:

{"מרחק": "KILOMETER"}

אל א מרחק. קילומטר לְהִתְנַגֵד:

עיר עיר = ObjectMapper חדש (). ReadValue (json, City.class); assertEquals (Distance.KILOMETER, city.getDistance ());

4.2. באמצעות @JsonValue

למדנו להשתמש @JsonValue לסדר את Enums. אנו יכולים להשתמש באותה הערה גם לניתוק עריקה. זה אפשרי מכיוון שערכי Enum הם קבועים.

ראשית, בואו נשתמש @JsonValue באחת משיטות הגטר - getMeters ():

מרחק ציבורי מרחק {... @JsonValue getMeters כפול ציבורי () {מטרים חוזרים; }}

כעת, ערך ההחזר של getMeters () השיטה מייצגת את אובייקטים Enum. לפיכך, בעת ביטול ערעור JSON לדוגמה:

{"מרחק": "0.0254"}

ג'קסון יחפש את האובייקט של Enum שיש לו getMeters () ערך החזר של 0.0254. במקרה זה, האובייקט הוא מֶרְחָק.אִינְטשׁ:

assertEquals (Distance.INCH, city.getDistance ()); 

4.3. באמצעות @JsonProperty

ה @JsonProperty הערה משמשת במקרי ספירה:

מרחק ציבורי מרחק {@JsonProperty ("מרחק-בק"מ") KILOMETER ("ק"מ", 1000), @JsonProperty ("מרחק-בקילומטרים") MILE ("מיילים", 1609.34); ...}

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

כתוצאה מההצהרה לעיל, מחרוזת JSON לדוגמא:

{"מרחק": "מרחק בקילומטר"}

ימופה ל מרחק. קילומטר לְהִתְנַגֵד:

assertEquals (Distance.KILOMETER, city.getDistance ());

4.4. באמצעות @JsonCreator

ג'קסון קורא לשיטות בהערות @JsonCreator כדי לקבל מופע של הכיתה הסוגרת.

שקול את ייצוג JSON:

{"distance": {"unit": "miles", "meters": 1609.34}}

עכשיו, בואו נגדיר את forValues ​​() שיטת המפעל עם @JsonCreator ביאור:

מרחק ציבורי מרחק {@JsonCreator מרחק סטטי ציבורי forValues ​​(@JsonProperty ("יחידה") יחידת מחרוזת, @JsonProperty ("מטרים") מטרים כפולים) {עבור (מרחק מרחק: Distance.values ​​()) {if (distance.unit. שווה (יחידה) && Double.compare (distance.meters, meters) == 0) {מרחק חזרה; }} להחזיר null; } ...}

שימו לב לשימוש ב- @JsonProperty ביאור כדי לאגד את שדות JSON עם ארגומנטים השיטה.

ואז, כאשר אנו מורידים את מדגם JSON, נקבל את התוצאה:

assertEquals (Distance.MILE, city.getDistance ());

4.5. שימוש בהתאמה אישית מוריד עריקה

ניתן להשתמש במכשיר deserializer מותאם אישית אם אף אחת מהטכניקות המתוארות אינה זמינה. לדוגמה, יתכן שאין לנו גישה לקוד המקור של Enum, או אולי אנו משתמשים בגרסת ג'קסון ישנה יותר שאינה תומכת באחת או יותר מההערות שכוסו עד כה.

על פי מאמר ההתאוששות המותאמת אישית שלנו, על מנת לבטל את ערעור ה- JSON שסופק בסעיף הקודם, נתחיל ביצירת מחלקת דה-ריליזציה:

מחלקה ציבורית CustomEnumDeserializer מרחיב את StdDeserializer {@Override public מרחק deserialize (JsonParser jsonParser, DeserializationContext ctxt) זורק IOException, JsonProcessingException {JsonNode node = jsonParser.getCodec (). readTer (jsonP) יחידת מחרוזת = node.get ("יחידה"). AsText (); מטר כפול = node.get ("מטרים"). asDouble (); עבור (Distance distance: Distance.values ​​()) {if (distance.getUnit (). שווה (יחידה) && Double.compare (distance.getMeters (), מטרים) == 0) {מרחק חזרה; }} להחזיר null; }} 

לאחר מכן, אנו משתמשים ב- @JsonDeserialize ביאור על Enum כדי לציין את deserializer המותאם אישית שלנו:

@JsonDeserialize (באמצעות = CustomEnumDeserializer.class) מרחק ציבורי מרחק ... {...}

והתוצאה שלנו היא:

assertEquals (Distance.MILE, city.getDistance ());

5. מסקנה

מאמר זה המחיש כיצד להשיג שליטה טובה יותר תהליכים ופורמטים סדרתיים ועריקול של Java Enums.

ניתן למצוא את היישום של כל הדוגמאות וקטעי הקוד ב- GitHub.


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