Demarširanje datuma korištenjem JAXB-a

1. Uvod

U ovom vodiču, vidjet ćemo kako ukloniti datumske objekte s različitim formatima pomoću JAXB-a.

Prvo ćemo pokriti zadani format datuma sheme. Zatim ćemo istražiti kako koristiti različite formate. Također ćemo vidjeti kako se možemo nositi s uobičajenim izazovom koji se javlja s ovim tehnikama.

2. Shema za Java vezanje

Prvi, moramo razumjeti odnos između XML sheme i tipova podataka Java. Konkretno, zanima nas mapiranje između XML sheme i Java datumskih objekata.

Prema Shema u mapiranje Java, postoje tri vrste podataka sheme koje moramo uzeti u obzir: xsd: datum, xsd: vrijeme i xsd: dateTime. Kao što vidimo, svi su oni mapirani javax.xml.datatype.XMLGregorianCalendar.

Također moramo razumjeti zadane formate za ove tipove XML sheme. The xsd: datum i xsd: vrijeme tipovi podataka imaju "GGGG-MM-DD ” i "hh: mm: ss ” formati. The xsd: dateTime format je "GGGG-MM-DDThh: mm: ss ” gdje "T " je separator koji označava početak vremenskog odjeljka.

3. Korištenje zadanog formata datuma sheme

Izgradit ćemo primjer da unmaršali datiraju objekte. Usredotočimo se na xsd: dateTime tip podataka jer je superset ostalih tipova.

Upotrijebimo jednostavnu XML datoteku koja opisuje knjigu:

 Knjiga1 1979-10-21T03: 31: 12 

Datoteku želimo preslikati na odgovarajuću Javu Knjiga objekt:

@XmlRootElement (name = "book") javna klasa Book {@XmlElement (name = "title", required = true) private String title; @XmlElement (ime = "objavljeno", potrebno = točno) objavljen privatni XMLGregorianCalendar; @Override public String toString () {return "[naslov:" + naslov + "; objavljeno:" + objavljeno.toString () + "]"; }}

Na kraju, moramo stvoriti klijentsku aplikaciju koja pretvara XML podatke u Java objekte izvedene iz JAXB:

javna statička knjiga unmarshalDates (InputStream inputFile) baca JAXBException {JAXBContext jaxbContext = JAXBContext.newInstance (Book.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller (); return (Knjiga) jaxbUnmarshaller.unmarshal (inputFile); }

U gornjem kodu definirali smo JAXBContext što je ulazna točka u JAXB API. Zatim smo koristili JAXB Unmaršaler na ulaznom toku kako bismo pročitali naš objekt:

Ako pokrenemo gornji kod i ispišemo rezultat, dobit ćemo sljedeće Knjiga objekt:

[naslov: Knjiga1; objavljeno: 1979-11-28T02: 31: 32]

To bismo trebali primijetiti, iako je zadano mapiranje za xsd: dateTime je XMLGregorianCalendar, mogli smo koristiti i uobičajenije tipove Java: java.util.Datum i java.util.Kalendar, prema korisničkom priručniku JAXB.

4. Korištenje prilagođenog formata datuma

Gornji primjer djeluje jer koristimo zadani format datuma sheme, "GGGG-MM-DDThh: mm: ss".

Ali što ako želimo koristiti drugi oblik poput "GGGG-MM-DD hh: mm: ss", rješavajući se "T" graničnik? Ako bismo zamijenili graničnik razmakom u našoj XML datoteci, zadano uklanjanje oznake ne bi uspjelo.

4.1. Izgradnja običaja XmlAdapter

Da bismo koristili drugačiji format datuma, moramo definirati XmlAdapter.

Pogledajmo i kako mapirati xsd: dateTime upišite u a java.util.Datum objekt s našim običajem XmlAdapter:

javna klasa DateAdapter proširuje XmlAdapter {private static final String CUSTOM_FORMAT_STRING = "yyyy-MM-dd HH: mm: ss"; @Override public String maršal (Date v) {return new SimpleDateFormat (CUSTOM_FORMAT_STRING) .format (v); } @Override public Date unmarshal (String v) baca ParseException {return new SimpleDateFormat (CUSTOM_FORMAT_STRING) .parse (v); }}

U ovom adapteru, koristili smoSimpleDateFormat za formatiranje našeg datuma. Moramo biti oprezni kao the SimpleDateFormat nije siguran u niti. Da biste izbjegli da više niti ima problema sa dijeljenim SimpleDateFormat objekt, stvaramo novi svaki put kad nam zatreba.

4.2. The XmlAdapter'S Internals

Kao što vidimo, XmlAdapter ima dva parametra tipa, u ovom slučaju, Niz i Datum. Prva je vrsta koja se koristi unutar XML-a i naziva se vrijednosnom vrstom. U ovom slučaju, JAXB zna pretvoriti XML vrijednost u Niz. Drugi se naziva vezanim tipom i odnosi se na vrijednost u našem Java objektu.

Cilj je adaptera pretvoriti između vrste vrijednosti i vezane vrste, na način koji JAXB ne može učiniti prema zadanim postavkama.

Da bi se izgradio običaj XmlAdapter, moramo nadjačati dvije metode: XmlAdapter.marshal () i XmlAdapter.unmarshal ().

Tijekom demarširanja, okvir vezivanja JAXB prvo demaršira XML predstavu u a Niz a zatim priziva DateAdapter.unmarshal () prilagoditi tip vrijednosti a Datum. Tijekom ranžiranja poziva se okvir vezivanja JAXB DateAdapter.marshal () prilagoditi a Datum do Niz, koji se zatim maršira u XML prikaz.

4.3. Integriranje putem JAXB napomena

The DatumAdapter radi poput dodatka za JAXB i pridružit ćemo ga našem polju datuma pomoću @XmlJavaTypeAdapter bilješka. The @XmlJavaTypeAdapter napomena specificira upotrebu an XmlAdapter za prilagođeno uklanjanje oznaka:

@XmlRootElement (name = "book") javna klasa BookDateAdapter {// isto kao i prije @XmlElement (name = "objavljeno", potrebno = točno) @XmlJavaTypeAdapter (DateAdapter.class) privatno Datum objavljivanja; // isto kao prije }

Također koristimo standardne JAXB napomene: @XmlRootElement i @XmlElement bilješke.

Na kraju, pokrenimo novi kod:

[naslov: Knjiga1; objavljeno: Srijeda, 28. studenoga 02:31:32 EET 1979]

5. Demarširanje datuma u Javi 8

Java 8 predstavila je novu Datum vrijeme API. Ovdje ćemo se usredotočiti na LocalDateTime razred koji je jedan od najčešće korištenih.

5.1. Izgradnja a LocalDateTime-na osnovi XmlAdapter

Prema zadanim postavkama, JAXB ne može automatski vezati datoteku xsd: dateTime vrijednost prema a LocalDateTime objekt bez obzira na format datuma. Da biste pretvorili vrijednost datuma XML sheme u ili iz LocalDateTime objekt, moramo definirati drugi XmlAdapter slično prethodnom:

javna klasa LocalDateTimeAdapter proširuje XmlAdapter {private DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern ("yyyy-MM-dd HH: mm: ss"); @Override public String marshal (LocalDateTime dateTime) {return dateTime.format (dateFormat); } @Override public LocalDateTime unmarshal (String dateTime) {return LocalDateTime.parse (dateTime, dateFormat); }}

U ovom slučaju, koristili smo a DateTimeFormatter umjesto a SimpleDateFormat. Prvi je predstavljen u Javi 8 i kompatibilan je s novim Datum vrijeme API.

Imajte na umu da operacije pretvorbe mogu dijeliti a DateTimeFormatter objekt jer the DateTimeFormatter zaštićen je nitima.

5.2. Integriranje novog adaptera

Zamijenimo sada stari adapter novim u našem Knjiga razred i također Datum s LocalDateTime:

@XmlRootElement (name = "book") javna klasa BookLocalDateTimeAdapter {// isto kao i prije @XmlElement (name = "objavljeno", potrebno = točno) @XmlJavaTypeAdapter (LocalDateTimeAdapter.class) objavljeno private LocalDateTime; // isto kao prije }

Ako pokrenemo gornji kod, dobit ćemo izlaz:

[naslov: Knjiga1; objavljeno: 1979-11-28T02: 31: 32]

Imajte na umu da LocalDateTime.toString () dodaje "T" graničnik između datuma i vremena.

6. Zaključak

U ovom smo tutorijalu istražili demarširanje datuma pomoću JAXB-a.

Prvo smo pogledali mapiranje tipa podataka XML Schema u Java i stvorili primjer koristeći zadani format datuma XML Schema.

Zatim smo naučili kako koristiti prilagođeni format datuma koji se temelji na prilagođenom XmlAdapter i vidio kako postupati sa sigurnošću niti SimpleDateFormat.

Konačno, iskoristili smo vrhunski API za datum / vrijeme Java 8 Date / Time i nemarširane datume s prilagođenim formatima.

Kao i uvijek, izvorni kod korišten u vodiču dostupan je na GitHub-u.