ביטול תאריך תאריך באמצעות JAXB

1. הקדמה

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

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

2. סכמה ל- Java Binding

ראשון, עלינו להבין את הקשר בין סכמת ה- XML ​​לסוג הנתונים של Java. בפרט, אנו מעוניינים במיפוי בין סכימת XML לאובייקטים של תאריך Java.

על פי מיפוי סכמה ל- Java, ישנם שלושה סוגי נתוני סכימה שעלינו לקחת בחשבון: xsd: תאריך, xsd: זמן ו xsd: dateTime. כפי שאנו רואים, כולם ממופים javax.xml.datatype.XMLGregorianCalendar.

עלינו להבין את הפורמטים המוגדרים כברירת מחדל לסוגי סכימת XML אלה. ה xsd: תאריך ו xsd: זמן לסוגי הנתונים יש "YYYY-MM-DD ” ו"hh: mm: ss ” פורמטים. ה xsd: dateTime הפורמט הוא “YYYY-MM-DDThh: mm: ss ” איפה "T ” הוא מפריד המציין את תחילת קטע הזמן.

3. שימוש בפורמט ברירת המחדל של סכימת התאריך

אנו הולכים לבנות דוגמה לפירוק תאריכים של אובייקטים. בואו נתמקד ב xsd: dateTime סוג נתונים מכיוון שמדובר בסופר-סט של הסוגים האחרים.

בואו נשתמש בקובץ XML פשוט המתאר ספר:

 ספר 1 1979-10-21T03: 31: 12 

אנו רוצים למפות את הקובץ ל- Java המתאים סֵפֶר לְהִתְנַגֵד:

@XmlRootElement (name = "book") public class ספר {@ XmlElement (name = "title", חובה = true) כותרת מחרוזת פרטית; @XmlElement (שם = "פורסם", חובה = נכון) פורסם XMLGregorianCalendar פרטי; @ עקוף ציבורי מחרוזת למחרוזת () {החזר "[כותרת:" + כותרת + "; פורסם:" + פורסם.למחרוזת () + "]"; }}

לבסוף, עלינו ליצור יישום לקוח הממיר את נתוני ה- XML ​​לאובייקטים של Java שמקורם ב- JAXB:

ספר סטטי ציבורי unmarshalDates (InputStream inputFile) זורק JAXBException {JAXBContext jaxbContext = JAXBContext.newInstance (Book.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller (); החזר (ספר) jaxbUnmarshaller.unmarshal (inputFile); }

בקוד שלעיל הגדרנו a JAXBContext המהווה נקודת כניסה ל- JAXB API. ואז השתמשנו ב- JAXB לא מתאר בזרם קלט על מנת לקרוא את האובייקט שלנו:

אם נפעיל את הקוד שלעיל ונדפיס את התוצאה, נקבל את הדברים הבאים סֵפֶר לְהִתְנַגֵד:

[כותרת: ספר 1; פורסם: 1979-11-28T02: 31: 32]

עלינו לציין זאת, למרות מיפוי ברירת המחדל עבור xsd: dateTime האם ה XMLGregorianCalendarהיינו יכולים גם להשתמש בסוגי Java הנפוצים יותר: java.util.Date ו java.util.Calendar, על פי מדריך המשתמש של JAXB.

4. שימוש בפורמט תאריך מותאם אישית

הדוגמה שלעיל עובדת מכיוון שאנו משתמשים בפורמט ברירת המחדל של תאריך הסכימה, "YYYY-MM-DDThh: mm: ss".

אבל מה אם נרצה להשתמש בפורמט אחר כמו "YYYY-MM-DD hh: mm: ss", להיפטר מה- "T" תוחם? אם היינו מחליפים את המפריד בתו רווח בקובץ ה- XML ​​שלנו, אי-אחסון ברירת המחדל ייכשל.

4.1. בניית מותאם אישית מתאם Xml

על מנת להשתמש בפורמט תאריך אחר, עלינו להגדיר מתאם Xml.

בואו נראה גם כיצד למפות את xsd: dateTime הקלד ל java.util.Date להתנגד למנהג שלנו מתאם Xml:

class class DateAdapter מרחיב את XmlAdapter {private static final מחרוזת CUSTOM_FORMAT_STRING = "yyyy-MM-dd HH: mm: ss"; @ Override מחרוזת מחרוזת ציבורית (תאריך v) {להחזיר SimpleDateFormat חדש (CUSTOM_FORMAT_STRING). פורמט (v); } @Override public תאריך unmarshal (מחרוזת v) זורק ParseException {להחזיר SimpleDateFormat חדש (CUSTOM_FORMAT_STRING) .parse (v); }}

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

4.2. ה מתאם Xmlפנימיות

כפי שאנו רואים, מתאם Xml יש שני פרמטרים מסוגים, במקרה הזה, חוּט ו תַאֲרִיך. הראשון הוא הסוג המשמש בתוך ה- XML ​​ונקרא סוג הערך. במקרה זה, JAXB יודע להמיר ערך XML ל- חוּט. השני נקרא סוג הכריכה ומתייחס לערך באובייקט הג'אווה שלנו.

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

על מנת לבנות מנהג Xmlמַתאֵםעלינו לבטל שתי שיטות: XmlAdapter.marshal () ו XmlAdapter.unmarshal ().

במהלך ביטול פרסום, מסגרת הכריכה של JAXB מבטלת תחילה את פרסום ייצוג ה- XML ​​ל- a חוּט ואז קורא DateAdapter.unmarshal () כדי להתאים את סוג הערך ל- a תַאֲרִיך. במהלך הפתיחה, מסגרת ה- JAXB מחייבת DateAdapter.marshal () להסתגל א תַאֲרִיך ל חוּט, שמופעל אז לייצוג XML.

4.3. שילוב באמצעות ההערות JAXB

ה תאריך מתאם עובד כמו תוסף ל- JAXB ואנחנו נקשר אותו לשדה התאריכים שלנו באמצעות ה- @XmlJavaTypeAdapter ביאור. ה @XmlJavaTypeAdapteביאור r מציין את השימוש ב- מתאם Xml עבור אי-התאמה אישית:

@XmlRootElement (name = "book") BookDateAdapter בכיתה ציבורית {// כמו שקודם לכן @XmlElement (name = "פרסם", חובה = true) @ XmlJavaTypeAdapter (DateAdapter.class) תאריך פרסום פרטי; // כמו מקודם }

אנו משתמשים גם בהערות JAXB הסטנדרטיות: @XmlRootElement ו @XmlElement ביאורים.

לבסוף, בואו נפעיל את הקוד החדש:

[כותרת: ספר 1; פורסם: ד '28 בנובמבר 02:31:32 EET 1979]

5. ביטול תאריך תאריך ב- Java 8

ג'אווה 8 הציגה חדש תאריך שעה ממשק API. הנה, אנו נתמקד ב LocalDateTime class שהוא אחד הנפוצים ביותר.

5.1. בונה LocalDateTime-מבוסס מתאם Xml

כברירת מחדל, JAXB לא יכול לאגד אוטומטית xsd: dateTime ערך ל- a LocalDateTime אובייקט ללא קשר לתבנית התאריך. על מנת להמיר ערך תאריך של סכימת XML ל- או ממנה LocalDateTime אובייקט, עלינו להגדיר אחר מתאם Xml דומה לזה הקודם:

מחלקה ציבורית LocalDateTimeAdapter מרחיב את XmlAdapter {private DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern ("yyyy-MM-dd HH: mm: ss"); @Override מחרוזת מחרוזת ציבורית (LocalDateTime dateTime) {return dateTime.format (dateFormat); } @Override LocalDateTime ציבורי unmarshal (מחרוזת dateTime) {להחזיר LocalDateTime.parse (dateTime, dateFormat); }}

במקרה הזה, השתמשנו ב- DateTimeFormatter במקום SimpleDateFormat. הראשון הוצג בג'אווה 8 והוא תואם לחדש תאריך שעה ממשק API.

שים לב שפעולות ההמרה יכולות לשתף א DateTimeFormatter חפץ בגלל ה DateTimeFormatter הוא בטוח בחוטים.

5.2. שילוב המתאם החדש

עכשיו, בואו נחליף את המתאם הישן לזה החדש שלנו סֵפֶר כיתה וגם תַאֲרִיך עם LocalDateTime:

@XmlRootElement (name = "book") BookLocalDateTimeAdapter בכיתה ציבורית {// אותו דבר כמו קודם @XmlElement (name = "שפורסם", חובה = true) @XmlJavaTypeAdapter (LocalDateTimeAdapter.class) פרטי LocalDateTime פורסם; // כמו מקודם }

אם נפעיל את הקוד שלעיל, נקבל את הפלט:

[כותרת: ספר 1; פורסם: 1979-11-28T02: 31: 32]

שים לב שה- LocalDateTime.toString () מוסיף "T" תוחם בין תאריך לשעה.

6. מסקנה

במדריך זה חקרנו ביטול אי-התאמות תאריכים באמצעות JAXB.

ראשית, בדקנו את מיפוי ה- XML ​​Schema ל- Java מסוג סוגי הנתונים ויצרנו דוגמה באמצעות תבנית התאריך המוגדרת כברירת מחדל של XML Schema.

לאחר מכן למדנו כיצד להשתמש בפורמט תאריך מותאם אישית המבוסס על מותאם אישית מתאם Xml וראה איך להתמודד עם בטיחות החוט של SimpleDateFormat.

לבסוף, השתמשנו בממשק ה- API 8 תאריך / שעה מעולה, הבטוח בשרשור, ב- Java 8 ובתאריכים לא מאוחסנים עם פורמטים מותאמים אישית.

כמו תמיד, קוד המקור המשמש במדריך זמין ב- GitHub.


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