Zrušenie zdieľania dátumov pomocou JAXB

1. Úvod

V tomto návode uvidíme, ako zrušiť klasifikáciu dátumových objektov v rôznych formátoch pomocou JAXB.

Najskôr pokryjeme predvolený formát dátumu schémy. Potom preskúmame, ako používať rôzne formáty. Uvidíme tiež, ako zvládneme bežnú výzvu, ktorá pri týchto technikách vyvstane.

2. Schéma na väzbu Java

Najprv, musíme pochopiť vzťah medzi schémou XML a údajovými typmi Java. Zaujíma nás predovšetkým mapovanie medzi schémou XML a objektmi dátumu Java.

Podľa Mapovanie schémy na Javu, musíme brať do úvahy tri dátové typy schémy: xsd: dátum, xsd: čas a xsd: dateTime. Ako vidíme, všetky sú namapované na javax.xml.datatype.XMLGregorianCalendar.

Musíme tiež porozumieť predvoleným formátom pre tieto typy schém XML. The xsd: dátum a xsd: čas dátové typy majú „RRRR-MM-DD “ a „hh: mm: ss ” formáty. The xsd: dateTime formát je „RRRR-MM-DDThh: mm: ss “ kde "T ” je oddeľovač označujúci začiatok časovej časti.

3. Používanie predvoleného formátu dátumu schémy

Budeme stavať príklad, že nemarshals datuje objekty. Zamerajme sa na xsd: dateTime dátový typ, pretože je to nadmnožina ostatných typov.

Použime jednoduchý súbor XML, ktorý popisuje knihu:

 Kniha1 1979-10-21T03: 31: 12 

Chceme namapovať súbor na zodpovedajúcu Javu Kniha objekt:

@XmlRootElement (name = "kniha") verejná trieda Kniha {@XmlElement (name = "title", required = true) názov súkromného reťazca; @XmlElement (name = "zverejnené", požadované = true) bol zverejnený súkromný XMLGregorianCalendar; @Override public String toString () {návrat "[názov:" + názov + "; zverejnené:" + zverejnené.toString () + "]"; }}

Nakoniec musíme vytvoriť klientsku aplikáciu, ktorá prevádza údaje XML na objekty Java odvodené od JAXB:

public static Book unmarshalDates (InputStream inputFile) hodí JAXBException {JAXBContext jaxbContext = JAXBContext.newInstance (Book.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller (); return (Kniha) jaxbUnmarshaller.unmarshal (inputFile); }

Vo vyššie uvedenom kóde sme definovali a JAXBContext čo je vstupný bod do rozhrania JAXB API. Potom sme použili JAXB Unmarshaller na vstupnom toku, aby sme mohli prečítať náš objekt:

Ak spustíme vyššie uvedený kód a vytlačíme výsledok, dostaneme nasledujúce Kniha objekt:

[názov: Kniha1; publikované: 1979-11-28T02: 31: 32]

Mali by sme na vedomie, že aj keď je predvolené mapovanie pre xsd: dateTime je XMLGregorianCalendar, mohli sme tiež použiť bežnejšie typy Java: java.util.Date a java.util.Calendar, podľa užívateľskej príručky JAXB.

4. Používanie vlastného formátu dátumu

Vyššie uvedený príklad funguje, pretože používame predvolený formát dátumu schémy, „RRRR-MM-DDThh: mm: ss“.

Ale čo keď chceme použiť iný formát ako „RRRR-MM-DD hh: mm: ss“, zbaviť sa „T“ oddeľovač? Ak by sme v našom súbore XML nahradili oddeľovač znakom medzery, predvolené zrušenie zdieľania by zlyhalo.

4.1. Budovanie zvyku XmlAdapter

Aby sme mohli použiť iný formát dátumu, musíme si definovať znak XmlAdapter.

Pozrime sa tiež, ako zmapovať xsd: dateTime napíš do a java.util.Date objekt s našim zvykom XmlAdapter:

verejná trieda DateAdapter rozširuje XmlAdapter {private static final String CUSTOM_FORMAT_STRING = "rrrr-MM-dd HH: mm: ss"; @Override public String marshal (Date v) {return new SimpleDateFormat (CUSTOM_FORMAT_STRING) .format (v); } @Override public Date unmarshal (String v) hodí ParseException {return new SimpleDateFormat (CUSTOM_FORMAT_STRING) .parse (v); }}

V tomto adaptéri sme použiliSimpleDateFormat naformátovať náš dátum. Musíme byť opatrní ako the SimpleDateFormat nie je bezpečný pre vlákna. Aby ste sa vyhli problémom s zdieľaním viacerých vlákien SimpleDateFormat objekt, vytvárame nový vždy, keď to potrebujeme.

4.2. The XmlAdapterVnútorných

Ako vidíme, XmlAdapter má dva parametre typu, v tomto prípade, String a Dátum. Prvý z nich je typ používaný vo vnútri XML a nazýva sa typ hodnoty. V takom prípade JAXB vie, ako previesť hodnotu XML na a String. Druhý sa nazýva viazaný typ a týka sa hodnoty v našom objekte Java.

Cieľom adaptéra je prevádzať medzi hodnotovým typom a viazaným typom spôsobom, ktorý JAXB štandardne nedokáže.

Za účelom vytvorenia zvyku XmlAdaptér, musíme prekonať dve metódy: XmlAdapter.marshal () a XmlAdapter.unmarshal ().

Počas zrušenia zdieľania rámec väzieb JAXB najskôr zruší rozdelenie reprezentácie XML na a String a potom vyvolá DateAdapter.unmarshal () prispôsobiť typ hodnoty a Dátum. Počas zaradenia sa vyvolá väzbový rámec JAXB DateAdapter.marshal () prispôsobiť sa a Dátum do String, ktorý je potom zaradený do reprezentácie XML.

4.3. Integrácia prostredníctvom anotácií JAXB

The DateAdapter funguje ako doplnok k JAXB a pripojíme ho k nášmu dátumovému poľu pomocou @XmlJavaTypeAdapter anotácia. The @XmlJavaTypeAdapteanotácia špecifikuje použitie XmlAdapter pre custom marshalling:

@XmlRootElement (name = "kniha") verejná trieda BookDateAdapter {// rovnaká ako predtým @XmlElement (name = "published", required = true) @XmlJavaTypeAdapter (DateAdapter.class) súkromné ​​Dátum zverejnenia; // rovnaké ako predtým }

Používame tiež štandardné anotácie JAXB: @XmlRootElement a @XmlElement anotácie.

Nakoniec spustíme nový kód:

[názov: Kniha1; publikované: St 28. novembra 02:31:32 EET 1979]

5. Dátumy zrušenia zdieľania v Jave 8

Java 8 predstavila nový Dátum Čas API. Tu sa zameriame na LocalDateTime triedy, ktorá je jednou z najbežnejšie používaných.

5.1. Budova a LocalDateTime- na základe XmlAdapter

Predvolene, JAXB nemôže automaticky viazať súbory xsd: dateTime hodnota do a LocalDateTime objekt bez ohľadu na formát dátumu. Za účelom prevodu hodnoty dátumu schémy XML na alebo z a LocalDateTime objektu, musíme si zadefinovať ďalší XmlAdapter podobný predchádzajúcemu:

verejná trieda LocalDateTimeAdapter rozširuje XmlAdapter {private DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern ("rrrr-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); }}

V tomto prípade, použili sme a DateTimeFormatter namiesto a SimpleDateFormat. Prvý z nich bol predstavený v prostredí Java 8 a je kompatibilný s novým Dátum Čas API.

Upozorňujeme, že operácie prevodu môžu zdieľať a DateTimeFormatter objekt, pretože the DateTimeFormatter je bezpečný pre vlákna.

5.2. Integrácia nového adaptéra

Teraz nahraďme starý adaptér za nový v našom Kniha trieda a tiež Dátum s LocalDateTime:

@XmlRootElement (name = "kniha") verejná trieda BookLocalDateTimeAdapter {// rovnaké ako predtým @XmlElement (name = "published", required = true) @XmlJavaTypeAdapter (LocalDateTimeAdapter.class) súkromné ​​LocalDateTime zverejnené; // rovnaké ako predtým }

Ak spustíme vyššie uvedený kód, dostaneme výstup:

[názov: Kniha1; publikované: 1979-11-28T02: 31: 32]

Všimnite si, že LocalDateTime.toString () dodáva „T“ oddeľovač medzi dátumom a časom.

6. Záver

V tomto návode sme preskúmali unsharing dáta pomocou JAXB.

Najskôr sme sa pozreli na mapovanie dátových typov XML Schema to Java a vytvorili sme príklad pomocou predvoleného formátu dátumu Schema XML.

Ďalej sme sa naučili, ako používať vlastný formát dátumu založený na obyčajnom XmlAdapter a videl, ako zaobchádzať s bezpečnosťou závitu SimpleDateFormat.

Nakoniec sme využili vynikajúce API bezpečné pre vlákna Java 8 Date / Time API a nezaradené dáta s vlastnými formátmi.

Ako vždy, zdrojový kód použitý v tomto výučbe je k dispozícii na GitHub.


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