ניתוח YAML עם SnakeYAML

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

במדריך זה נלמד כיצד להשתמש בספריית SnakeYAML כדי סדר סדרת אובייקטים של Java למסמכי YAML ולהיפך.

2. הגדרת פרויקט

על מנת להשתמש ב- SnakeYAML בפרויקט שלנו, נוסיף את התלות הבאה של Maven (הגרסה האחרונה תוכל למצוא כאן):

 org.yaml snakeyaml 1.21 

3. נקודת כניסה

ה יאמל class הוא נקודת הכניסה של ה- API:

יאמל יאמל = יאמל חדש ();

מכיוון שההטמעה אינה בטוחה בחוטים, נושאים שונים חייבים להיות משלהם יאמל למשל.

4. טעינת מסמך YAML

הספרייה מספקת תמיכה לטעינת המסמך מ- חוּט או InputStream. עיקר דגימות הקוד כאן יתבססו על ניתוח ה- InputStream.

נתחיל בהגדרת מסמך YAML פשוט ונקרא שם לקובץ לקוח.יאמל:

firstName: "John" שם משפחה: "Doe" גיל: 20

4.1. שימוש בסיסי

כעת ננתח את מסמך YAML הנ"ל עם ה- יאמל מעמד:

יאמל יאמל = יאמל חדש (); InputStream inputStream = this.getClass () .getClassLoader () .getResourceAsStream ("customer.yaml"); Map obj = yaml.load (inputStream); System.out.println (obj);

הקוד לעיל מייצר את הפלט הבא:

{firstName = John, lastName = Doe, age = 20}

כברירת מחדל, ה- לִטעוֹן() שיטה מחזירה א מַפָּה למשל. שאילתות על מַפָּה התנגדות בכל פעם תדרוש מאיתנו לדעת את שמות מפתח הנכסים מראש, וזה גם לא קל לעבור על נכסים מקוננים.

4.2. סוג מותאם אישית

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

בואו נגדיר א צרכן בכיתה ונסה לטעון את המסמך שוב:

לקוח בכיתה ציבורית {פרטי מחרוזת שם פרטי; שם משפחה פרטי מחרוזת; גיל פרטי פרטי; // גטרים וקובעים}

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

בואו נעדכן את המסמך ונשמור אותו בקובץ חדש customer_with_type.yaml:

!! com.baeldung.snakeyaml.Customer firstName: שם משפחה "John": "Doe" גיל: 20

שימו לב לשורה הראשונה במסמך, המכילה את המידע אודות הכיתה בה יש להשתמש בעת טעינה.

כעת נעדכן את הקוד המשמש לעיל ונעביר את שם הקובץ החדש כקלט:

יאמל יאמל = יאמל חדש (); InputStream inputStream = this.getClass () .getClassLoader () .getResourceAsStream ("yaml / customer_with_type.yaml"); לקוח לקוח = yaml.load (inputStream); 

ה לִטעוֹן() השיטה מחזירה כעת מופע של צרכן סוּג. החיסרון בגישה זו הוא שיש לייצא את הסוג כספרייה בכדי להשתמש בו במידת הצורך.

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

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

עכשיו עם טעינת ה- customer.yaml, נקבל את צרכן לְהִתְנַגֵד:

Yaml yaml = Yaml חדש (קונסטרוקטור חדש (Customer.class));

4.3. סוגים מרומזים

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

לדוגמה:

1.0 -> לצוף 42 -> מספר שלם 2009-03-30 -> תאריך

בואו נבדוק המרה מסוג זה מרומז באמצעות מקרה מבחן:

@ מבחן ציבורי בטל כאשר LoadYAML_thenLoadCorrectImplicitTypes () {Yaml yaml = new Yaml (); מסמך מפה = yaml.load ("3.0: 22/07/2018"); assertNotNull (מסמך); assertEquals (1, document.size ()); assertTrue (document.containsKey (3.0d)); }

4.4. אובייקטים מקוננים ואוספים

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

בואו נוסיף איש קשר ו כתובת פרטים ל customer.yaml, ושמור את הקובץ החדש כ- customer_with_contact_details_and_address.yaml.

כעת ננתח את מסמך YAML החדש:

שם פרטי: "John" שם משפחה: "Doe" גיל: 31 contactDetails: - סוג: "mobile" מספר: 123456789 - type: "מספר טלפון קווי": 456786868 home כתובת: שורה: "Xyz, DEF Street" עיר: "עיר Y" : מיקוד "מדינה Y": 345657 

צרכן הכיתה צריכה לשקף גם שינויים אלה. הנה השיעור המעודכן:

לקוח בכיתה ציבורית {פרטי מחרוזת שם פרטי; שם משפחה פרטי מחרוזת; גיל פרטי פרטי; רשימת פרטי contactDetails; כתובת ביתית פרטית כתובת; // גטרים וקובעים} 

בואו נראה איך איש קשר ו כתובת השיעורים נראים כמו:

מעמד ציבורי צור קשר {פרטי סוג מחרוזת; מספר אינטראקטיבי פרטי; // גטרים וקובעים}
כתובת בכיתה ציבורית {קו מחרוזת פרטי; עיר מיתרים פרטית; מדינת מיתרים פרטית; רוכסן פרטי שלם; // גטרים וקובעים}

עכשיו נבדוק את יאמל#לִטעוֹן() עם מקרה הבדיקה הנתון:

@Test הציבור בטל כאשר LoadYAMLDocumentWithTopLevelClass_thenLoadCorrectJavaObjectWithNestedObjects () {Yaml yaml = Yaml new (Constructor new (Customer.class)); InputStream inputStream = this.getClass () .getClassLoader () .getResourceAsStream ("yaml / customer_with_contact_details_and_address.yaml"); לקוח לקוח = yaml.load (inputStream); assertNotNull (לקוח); assertEquals ("John", customer.getFirstName ()); assertEquals ("איילה", customer.getLastName ()); assertEquals (31, customer.getAge ()); assertNotNull (customer.getContactDetails ()); assertEquals (2, customer.getContactDetails (). size ()); assertEquals ("mobile", customer.getContactDetails () .get (0) .getType ()); assertEquals (123456789, customer.getContactDetails () .get (0) .getNumber ()); assertEquals ("קוויים", customer.getContactDetails () .get (1) .getType ()); assertEquals (456786868, customer.getContactDetails () .get (1) .getNumber ()); assertNotNull (customer.getHomeAddress ()); assertEquals ("Xyz, DEF Street", customer.getHomeAddress () .getLine ()); }

4.5. אוספים מסוג בטוח

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

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

firstName: "John" שם משפחה: "Doe" גיל: 31 contactDetails: - {type: "mobile", number: 123456789} - {type: "landline", number: 123456789}

על מנת לטעון מסמך זה, אנחנו יכולים לציין את TypeDescription עבור הנכס הנתון בכיתה העליונה:

קונסטרוקטור קונסטרוקטור = קונסטרוקטור חדש (Customer.class); TypeDescription customTypeDescription = חדש TypeDescription (Customer.class); customTypeDescription.addPropertyParameters ("contactDetails", Contact.class); constructor.addTypeDescription (customTypeDescription); יאמל יאמל = יאמל חדש (קונסטרוקטור);

4.6. טוען מסמכים מרובים

יכולים להיות מקרים שבהם, בסינגל אחד קוֹבֶץ ישנם מספר מסמכי YAML, ואנחנו רוצים לנתח את כולם. ה יאמל הכיתה מספקת א loadAll () שיטה לבצע ניתוח כזה.

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

שקול את המסמכים הבאים בקובץ יחיד:

--- firstName: "John" שם משפחה: "Doe" גיל: 20 --- firstName: "Jack" שם משפחה: "Jones" גיל: 25

אנו יכולים לנתח את האמור לעיל באמצעות ה- loadAll () שיטה כפי שמוצג בדוגמת הקוד שלהלן:

@Test הציבור מבוטל כאשר LoadMultipleYAMLDocuments_thenLoadCorrectJavaObjects () {Yaml yaml = Yaml new (קונסטרוקטור חדש (Customer.class)); InputStream inputStream = this.getClass () .getClassLoader () .getResourceAsStream ("yaml / customers.yaml"); ספירת int = 0; עבור (אובייקט אובייקט: yaml.loadAll (inputStream)) {count ++; assertTrue (אובייקט של הלקוח); } assertEquals (2, count); }

5. השלכת מסמכי YAML

הספרייה מספקת גם שיטה ל זרוק אובייקט Java נתון למסמך YAML. התפוקה יכולה להיות חוּט או קובץ / זרם שצוין.

5.1. שימוש בסיסי

נתחיל בדוגמה פשוטה של ​​השלכת מופע של מַפָּה למסמך YAML (חוּט):

@Test ציבורי בטל כאשרDumpMap_thenGenerateCorrectYAML () {Map data = new LinkedHashMap (); data.put ("name", "Silenthand Olleander"); data.put ("גזע", "אנושי"); data.put ("תכונות", מחרוזת חדשה [] {"ONE_HAND", "ONE_EYE"}); יאמל יאמל = יאמל חדש (); סופר StringWriter = חדש StringWriter (); yaml.dump (נתונים, כותב); מחרוזת expectYaml = "שם: Silenthand Olleander \ nrace: אנושי \ n תכונות: [ONE_HAND, ONE_EYE] \ n"; assertEquals (expectYaml, writer.toString ()); }

הקוד שלעיל מייצר את הפלט הבא (שימו לב כי שימוש במופע של LinkedHashMap שומר על סדר נתוני הפלט):

שם: גזע אוליאנדר שקט ידני: תכונות אנושיות: [ONE_HAND, ONE_EYE]

5.2. אובייקטים מותאמים אישית של Java

אנחנו יכולים גם לבחור זרוק סוגי Java מותאמים אישית לזרם פלט. עם זאת, זה יוסיף את המפורש הגלובלי תָג למסמך הפלט:

@ מבחן ציבורי בטל כאשרDumpACustomType_thenGenerateCorrectYAML () {לקוח לקוח = לקוח חדש (); customer.setAge (45); customer.setFirstName ("גרג"); customer.setLastName ("מקדואל"); יאמל יאמל = יאמל חדש (); סופר StringWriter = חדש StringWriter (); yaml.dump (לקוח, סופר); מחרוזת expectYaml = "!! com.baeldung.snakeyaml.Customer {age: 45, contactDetails: null, firstName: Greg, \ n homeAddress: null, lastName: McDowell} \ n"; assertEquals (expectYaml, writer.toString ()); }

לפי הגישה הנ"ל, אנו עדיין משליכים את פרטי התג במסמך YAML.

פירוש הדבר שעלינו לייצא את הכיתה שלנו כספרייה לכל צרכן שמבטל אותה מחדש. על מנת להימנע משם התג בקובץ הפלט, אנו יכולים להשתמש ב- dumpAs () השיטה המסופקת על ידי הספרייה.

אז בקוד שלעיל, נוכל לשנות את הדברים הבאים כדי להסיר את התג:

yaml.dumpAs (לקוח, Tag.MAP, null);

6. מסקנה

מאמר זה המחיש את השימושים בספריית SnakeYAML לסידור אובייקטים של Java ל- YAML ולהיפך.

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


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