Korisnički vodič za XStream: Pretvaranje objekata u XML

1. Pregled

U ovom uputstvu naučit ćemo kako koristiti knjižnicu XStream za serializaciju Java objekata u XML.

2. Značajke

Postoji nekoliko zanimljivih prednosti korištenja XStreama za serializaciju i deserializaciju XML-a:

  • Pravilno konfiguriran, proizvodi vrlo čisti XML
  • Pruža značajne mogućnosti za prilagođavanje XML izlaza
  • Podrška za grafovi objekata, uključujući kružne reference
  • Za većinu slučajeva korištenja, instanca XStream je bez niti, jednom konfigurirano (postoje upozorenja pri korištenju napomena)
  • Jasne poruke pružaju se tijekom rukovanje iznimkama za pomoć u dijagnosticiranju problema
  • Počevši od verzije 1.4.7, imamo sigurnosne značajke dostupan za onemogućavanje serializacije određenih vrsta

3. Postavljanje projekta

Da bismo koristili XStream u našem projektu, dodati ćemo sljedeću Mavenovu ovisnost:

 com.thoughtworks.xstream xstream 1.4.9 

4. Osnovna upotreba

The XStream klasa je fasada za API. Prilikom izrade instance XStream, moramo voditi računa i o problemima sigurnosti niti:

XStream xstream = novi XStream ();

Jednom kada se instanca kreira i konfigurira, može se dijeliti s više niti za marširanje / uklanjanje marširanja, osim ako ne omogućite obradu napomena.

4.1. Vozači

Podržano je nekoliko upravljačkih programa, poput DomDriver, StaxDriver, XppDriver, i više. Ovi pokretački programi imaju različite performanse i karakteristike korištenja resursa.

Pogonitelj XPP3 koristi se prema zadanim postavkama, ali naravno, upravljač možemo lako promijeniti:

XStream xstream = novi XStream (novi StaxDriver ()); 

4.2. Generiranje XML-a

Počnimo s definiranjem jednostavnog POJO za - Kupac:

kupac javne klase {private String firstName; private String lastName; privatno Datum dob; // standardni konstruktor, postavljači i getteri}

Generirajmo sada XML predstavu objekta:

Kupac kupac = novi kupac ("John", "Doe", novi datum ()); Niz podatakaXml = xstream.toXML (kupac);

Koristeći zadane postavke, dobiva se sljedeći izlaz:

 John Doe 1986-02-14 03: 46: 16.381 UTC 

Iz ovog rezultata možemo jasno vidjeti da sadrži oznaka koristi potpuno kvalificirano ime klase Kupac prema zadanim postavkama.

Postoji mnogo razloga zbog kojih bismo mogli odlučiti da zadano ponašanje ne odgovara našim potrebama. Na primjer, možda nam ne bi bilo ugodno izlagati strukturu paketa naše aplikacije. Također, generirani XML znatno je duži.

5. pseudonimi

An alias je ime koje želimo koristiti za elemente umjesto da koristimo zadana imena.

Na primjer, možemo zamijeniti com.baeldung.pojo.Kupac s kupac registracijom zamjenskog imena za Kupac razred. Također možemo dodati pseudonime za svojstva klase. Korištenjem zamjenskih imena možemo učiniti naš XML izlaz mnogo čitljivijim i manje specifičnim za Java.

5.1. Razredni pseudonimi

Pseudonimi se mogu registrirati bilo programski ili pomoću bilješki.

Ajmo sada bilježiti naše Kupac razred sa @XStreamAlias:

@XStreamAlias ​​("kupac")

Sada moramo konfigurirati našu instancu da koristi ovu napomenu:

xstream.processAnnotations (Customer.class);

Ako želimo programski konfigurirati alias, možemo koristiti donji kod:

xstream.alias ("kupac", kupac.klasa);

Bez obzira koristi li zamjensko ime ili programsku konfiguraciju, izlaz za Kupac objekt će biti puno čišći:

 John Doe 1986-02-14 03: 46: 16.381 UTC 

5.2. Poljski pseudonimi

Također možemo dodati aliase za polja koristeći istu napomenu koja se koristi za klase aliasinga. Na primjer, ako smo željeli polje ime zamijeniti s fn u XML predstavljanju mogli bismo upotrijebiti sljedeću napomenu:

@XStreamAlias ​​("fn") private String firstName;

Alternativno, isti cilj možemo postići programski:

xstream.aliasField ("fn", Customer.class, "firstName");

The aliasField metoda prihvaća tri argumenta: alias koji želimo koristiti, klasu u kojoj je svojstvo definirano i ime svojstva koje želimo alias.

Koja god se metoda koristi, izlaz je isti:

 John Doe 1986-02-14 03: 46: 16.381 UTC 

5.3. Zadane pseudonime

Nekoliko je zamjenskih imena predbilježenih za nastavu - evo nekoliko od njih:

alias ("float", Float.class); alias ("datum", Date.class); alias ("gregorijanski kalendar", Calendar.class); alias ("url", URL.class); alias ("popis", List.class); alias ("locale", Locale.class); alias ("valuta", Currency.class);

6. Zbirke

Sada ćemo dodati popis ContactDetails unutar Kupac razred.

privatni popis contactDetailsList;

Sa zadanim postavkama za rukovanje zbirkom, ovo je izlaz:

 John Doe 14.02.1986. 04: 14: 05.874 UTC 6673543265 0124-2460311 4676543565 0120-223312 

Pretpostavimo da moramo izostaviti contactDetailsList nadređene oznake, a mi samo želimo svaku ContactDetails element biti dijete od kupac element. Ponovno izmijenimo naš primjer:

xstream.addImplicitCollection (Customer.class, "contactDetailsList");

Sada, kada se generira XML, izostavljaju se korijenske oznake, što rezultira donjim XML-om:

 John Doe 14.02.1866. 04: 14: 20.541 UTC 6673543265 0124-2460311 4676543565 0120-223312 

Isto se također može postići korištenjem napomena:

@XStreamImplicit privatni popis contactDetailsList;

7. Pretvarači

XStream koristi mapu Konverter instance, svaka sa svojom strategijom pretvorbe. Oni pretvaraju isporučene podatke u određeni format u XML-u i natrag.

Osim korištenja zadanih pretvarača, možemo mijenjati zadane vrijednosti ili registrirati prilagođene pretvarače.

7.1. Izmjena postojećeg pretvarača

Pretpostavimo da nismo bili zadovoljni načinom na koji dob generirane su oznakepomoću zadanih postavki. Možemo prilagoditi prilagođeni pretvarač za Datum pruža XStream (Pretvarač datuma):

xstream.registerConverter (novi DateConverter ("dd-MM-yyyy", null));

Gore navedeno će dati izlaz u "dd-MM-yyyy" format:

 John Doe 14-02-1986 

7.2. Prilagođeni pretvarači

Također možemo stvoriti prilagođeni pretvarač kako bismo postigli isti izlaz kao u prethodnom odjeljku:

javna klasa MyDateConverter implementira Converter {private SimpleDateFormat formatter = new SimpleDateFormat ("dd-MM-yyyy"); @Override public boolean canConvert (Class clazz) {return Date.class.isAssignableFrom (clazz); } @Override public void marshal (Vrijednost objekta, HierarchicalStreamWriter Writer, MarshallingContext arg2) {Vrijednost datuma = (Datum); Writer.setValue (formatter.format (datum)); } // ostale metode}

Napokon, registriramo svoj MyDateConverter razred kao u nastavku:

xstream.registerConverter (novi MyDateConverter ());

Također možemo stvoriti pretvarače koji implementiraju SingleValueConverter sučelje, koje je dizajnirano za pretvaranje objekta u niz.

javna klasa MySingleValueConverter implementira SingleValueConverter {@Override public boolean canConvert (Class clazz) {return Customer.class.isAssignableFrom (clazz); } @Override javni niz toString (objekt objekta) {SimpleDateFormat formatter = novi SimpleDateFormat ("dd-MM-yyyy"); Datum datum = ((Kupac) obj) .getDob (); return ((kupac) obj) .getFirstName () + "," + ((kupac) obj) .getLastName () + "," + formatter.format (datum); } // ostale metode}

Napokon se registriramo MySingleValueConverter:

xstream.registerConverter (novi MySingleValueConverter ()); 

Koristeći MySingleValueConverter, XML izlaz za Kupac je kako slijedi:

Ivan, Doe, 14-02-1986

7.3. Prioritet pretvarača

Pri registraciji Konverter objekata, moguće je postaviti i razinu prioriteta.

Iz XStream javadocs:

Pretvarači se mogu registrirati s izričitim prioritetom. Prema zadanim postavkama registrirani su s XStream.PRIORITY_NORMAL. Pretvarači istog prioriteta koristit će se obrnutim redoslijedom u kojem su registrirani. Zadani pretvarač, tj. Pretvarač koji će se koristiti ako nijedan drugi registrirani pretvarač nije prikladan, može se registrirati s prioritetom XStream.PRIORITY_VERY_LOW. XStream prema zadanim postavkama koristi ReflectionConverter kao zamjenski pretvarač.

API nudi nekoliko imenovanih vrijednosti prioriteta:

privatni statički konačni int PRIORITY_NORMAL = 0; privatni statički konačni int PRIORITY_LOW = -10; privatni statički konačni int PRIORITY_VERY_LOW = -20; 

8.Izostavljanje polja

Polja iz generiranog XML-a možemo izostaviti pomoću bilješki ili programske konfiguracije. Da bismo izostavili polje pomoću napomene, jednostavno primjenjujemo @XStreamOmitField napomena o dotičnom polju:

@XStreamOmitField privatni niz firstName;

Da bismo programski izostali polje, koristimo sljedeću metodu:

xstream.omitField (Customer.class, "firstName");

Koju god metodu odabrali, izlaz je isti:

 Srna 14-02-1986 

9. Polja atributa

Ponekad bismo mogli željeti serializirati polje kao atribut elementa, a ne kao sam element. Pretpostavimo da dodamo a contactType polje:

private String contactType;

Ako želimo postaviti contactType kao XML atribut možemo koristiti @XStreamAsAttribute napomena:

@XStreamAsAttribute private String contactType; 

Alternativno, isti cilj možemo postići programski:

xstream.useAttributeFor (ContactDetails.class, "contactType");

Rezultat bilo koje od gore navedenih metoda je isti:

 6673543265 0124-2460311 

10. Istodobnost

Model obrade XStreama predstavlja neke izazove. Jednom kada je instanca konfigurirana, ona je sigurna u nitima.

Važno je napomenuti da obrada bilješki mijenja konfiguraciju neposredno prije marširanja / uklanjanja marširanja. I zato - ako trebamo da se instanca konfigurira u letu pomoću napomena, općenito je dobra ideja koristiti zasebnu XStream primjer za svaku nit.

11. Zaključak

U ovom smo članku pokrili osnove korištenja XStreama za pretvaranje objekata u XML. Također smo naučili o prilagodbama koje možemo koristiti da bismo osigurali da XML izlaz zadovoljava naše potrebe. Konačno, pregledali smo probleme s sigurnošću niti s napomenama.

U sljedećem članku iz ove serije naučit ćemo o pretvaranju XML-a natrag u Java objekte.

Cjeloviti izvorni kôd za ovaj članak može se preuzeti s povezanog spremišta GitHub.


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