XStream Brugervejledning: Konvertering af objekter til XML

1. Oversigt

I denne vejledning lærer vi, hvordan du bruger XStream-biblioteket til at serialisere Java-objekter til XML.

2. Funktioner

Der er en hel del interessante fordele ved at bruge XStream til at serialisere og deserialisere XML:

  • Konfigureret korrekt producerer det meget ren XML
  • Giver betydelige muligheder for tilpasning af XML-output
  • Støtte for objektgrafer, inklusive cirkulære referencer
  • I de fleste brugssager er XStream-forekomsten trådsikker, når den er konfigureret (der er advarsler, når du bruger annoteringer)
  • Rydde meddelelser leveres under undtagelse håndtering for at hjælpe med at diagnosticere problemer
  • Startende med version 1.4.7 har vi sikkerhedsfunktioner tilgængelig for at tillade serialisering af bestemte typer

3. Opsætning af projekt

For at bruge XStream i vores projekt vil vi tilføje følgende Maven-afhængighed:

 com.thoughtworks.xstream xstream 1.4.9 

4. Grundlæggende anvendelse

Det XStream klasse er en facade for API'et. Når du opretter en forekomst af XStream, vi skal også tage os af trådsikkerhedsspørgsmål:

XStream xstream = ny XStream ();

Når en instans er oprettet og konfigureret, kan den deles på tværs af flere tråde til marshalling / unmarshalling, medmindre du aktiverer annoteringsbehandling.

4.1. Chauffører

Flere drivere understøttes, f.eks DomDriver, StaxDriver, XppDriver, og mere. Disse drivere har forskellige egenskaber for ydeevne og ressourceforbrug.

XPP3-driveren bruges som standard, men selvfølgelig kan vi nemt ændre driveren:

XStream xstream = ny XStream (ny StaxDriver ()); 

4.2. Genererer XML

Lad os starte med at definere en simpel POJO til - Kunde:

offentlig klasse kunde {privat streng fornavn; privat streng efternavn; private Date dob; // standard konstruktør, settere og getters}

Lad os nu generere en XML-repræsentation af objektet:

Kundekunde = ny kunde ("John", "Doe", ny dato ()); Streng dataXml = xstream.toXML (kunde);

Ved hjælp af standardindstillingerne produceres følgende output:

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

Fra denne output kan vi tydeligt se, at det indeholdende tag bruger det fuldt kvalificerede klassenavn på Kunde som standard.

Der er mange grunde til, at vi måske beslutter, at standardadfærden ikke passer til vores behov. For eksempel er vi måske ikke komfortable med at udsætte pakkestrukturen for vores applikation. Den genererede XML er også betydeligt længere.

5. Aliaser

En alias er et navn, vi ønsker at bruge til elementer i stedet for at bruge standardnavne.

For eksempel kan vi erstatte com.baeldung.pojo.Kunde med kunde ved at registrere et alias til Kunde klasse. Vi kan også tilføje aliaser til egenskaber for en klasse. Ved at bruge aliaser kan vi gøre vores XML-output meget mere læsbart og mindre Java-specifikt.

5.1. Klassealiaser

Aliaser kan registreres enten programmatisk eller ved hjælp af annoteringer.

Lad os nu kommentere vores Kunde klasse med @XStreamAlias:

@XStreamAlias ​​("kunde")

Nu skal vi konfigurere vores forekomst til at bruge denne kommentar:

xstream.processAnnotations (kunde.klasse);

Alternativt, hvis vi ønsker at konfigurere et alias programmatisk, kan vi bruge koden nedenfor:

xstream.alias ("kunde", Customer.class);

Uanset om du bruger aliaset eller programmatisk konfiguration, vil output for en Kunde genstand vil være meget renere:

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

5.2. Markaliaser

Vi kan også tilføje aliaser for felter ved hjælp af den samme kommentar, der bruges til aliasingsklasser. For eksempel hvis vi ville have feltet fornavn udskiftes med fn i XML-repræsentationen kunne vi bruge følgende kommentar:

@XStreamAlias ​​("fn") privat streng fornavn;

Alternativt kan vi opnå det samme mål programmatisk:

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

Det aliasField metoden accepterer tre argumenter: det alias, vi ønsker at bruge, klassen, hvor egenskaben er defineret, og ejendomsnavnet, vi ønsker at alias.

Uanset hvilken metode der anvendes, er output det samme:

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

5.3. Standardaliaser

Der er flere aliasser, der er præregistreret til klasser - her er et par af disse:

alias ("float", Float.class); alias ("dato", Date.class); alias ("gregorian-calendar", Calendar.class); alias ("url", URL.class); alias ("liste", List.class); alias ("locale", Locale.class); alias ("valuta", Currency.class);

6. Samlinger

Nu vil vi tilføje en liste over Kontaktoplysninger inde i Kunde klasse.

privat liste contactDetailsList;

Med standardindstillinger til indsamlingshåndtering er dette output:

 John Doe 1986-02-14 04: 14: 05.874 UTC 6673543265 0124-2460311 4676543565 0120-223312 

Lad os antage, at vi er nødt til at udelade contactDetailsList forældremærker, og vi vil bare hver Kontaktoplysninger element for at være barn af kunde element. Lad os ændre vores eksempel igen:

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

Når XML er genereret, udelades rodtags nu, hvilket resulterer i XML nedenfor:

 John Doe 1986-02-14 04: 14: 20.541 UTC 6673543265 0124-2460311 4676543565 0120-223312 

Det samme kan også opnås ved hjælp af annoteringer:

@XStreamImplicit privat liste contactDetailsList;

7. Konvertere

XStream bruger et kort over Konverter forekomster, hver med sin egen konverteringsstrategi. Disse konverterer leverede data til et bestemt format i XML og tilbage igen.

Ud over at bruge standardkonvertere kan vi ændre standardindstillingerne eller registrere brugerdefinerede konvertere.

7.1. Ændring af en eksisterende konverter

Antag, at vi ikke var tilfredse med den måde, hvorpå dob tags blev genereretved hjælp af standardindstillingerne. Vi kan ændre den tilpassede konverter til Dato leveret af XStream (DateConverter):

xstream.registerConverter (ny DateConverter ("dd-MM-åååå", null));

Ovenstående producerer output i “dd-MM-åååå" format:

 John Doe 14-02-1986 

7.2. Brugerdefinerede konvertere

Vi kan også oprette en brugerdefineret konverter til at opnå den samme output som i det foregående afsnit:

offentlig klasse MyDateConverter implementerer Converter {private SimpleDateFormat formatter = ny SimpleDateFormat ("dd-MM-åååå"); @ Override public boolean canConvert (Class clazz) {return Date.class.isAssignableFrom (clazz); } @ Override public void marshal (Objektværdi, HierarchicalStreamWriter-forfatter, MarshallingContext arg2) {Date date = (Date) value; writer.setValue (formatter.format (dato)); } // andre metoder}

Endelig registrerer vi vores MyDateConverter klasse som nedenfor:

xstream.registerConverter (ny MyDateConverter ());

Vi kan også oprette konvertere, der implementerer SingleValueConverter interface, som er designet til at konvertere et objekt til en streng.

offentlig klasse MySingleValueConverter implementerer SingleValueConverter {@Override public boolean canConvert (Class clazz) {return Customer.class.isAssignableFrom (clazz); } @ Override public String toString (Objekt obj) {SimpleDateFormat formatter = ny SimpleDateFormat ("dd-MM-åååå"); Dato dato = ((kunde) obj) .getDob (); returnere ((kunde) obj) .getFirstName () + "," + ((kunde) obj) .getLastName () + "," + formatter.format (dato); } // andre metoder}

Endelig registrerer vi os MySingleValueConverter:

xstream.registerConverter (ny MySingleValueConverter ()); 

Ved brug af MySingleValueConverter, XML-output for en Kunde er som følgende:

John, Doe, 14-02-1986

7.3. Konverteringsprioritet

Ved tilmelding Konverter objekter, er det også muligt at indstille deres prioritetsniveau.

Fra XStream-javadocs:

Omformerne kan registreres med en eksplicit prioritet. Som standard er de registreret hos XStream.PRIORITY_NORMAL. Konvertere med samme prioritet vil blive brugt i den omvendte rækkefølge, de er blevet registreret. Standardkonverteren, dvs. den konverter, der vil blive brugt, hvis ingen anden registreret konverter er egnet, kan registreres med prioritet XStream.PRIORITY_VERY_LOW. XStream bruger som standard ReflectionConverter som reservekonverter.

API'en indeholder flere navngivne prioritetsværdier:

privat statisk endelig int PRIORITY_NORMAL = 0; privat statisk endelig int PRIORITY_LOW = -10; privat statisk endelig int PRIORITY_VERY_LOW = -20; 

8.Udeladelse af felter

Vi kan udelade felter fra vores genererede XML ved hjælp af enten kommentarer eller programmatisk konfiguration. For at udelade et felt ved hjælp af en kommentar anvender vi simpelthen @XStreamOmitField kommentar til det pågældende felt:

@XStreamOmitField privat streng fornavn;

For at udelade feltet programmatisk bruger vi følgende metode:

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

Uanset hvilken metode vi vælger, er output det samme:

 Doe 14-02-1986 

9. Attributter

Nogle gange ønsker vi muligvis at serieisere et felt som en attribut for et element snarere end som et element selv. Antag, at vi tilføjer en contactType Mark:

privat streng contactType;

Hvis vi vil indstille contactType som en XML-attribut kan vi bruge @XStreamAsAttribute kommentar:

@XStreamAsAttribute private String contactType; 

Alternativt kan vi opnå det samme mål programmatisk:

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

Outputtet fra en af ​​ovenstående metoder er det samme:

 6673543265 0124-2460311 

10. Samtidighed

XStreams behandlingsmodel giver nogle udfordringer. Når forekomsten er konfigureret, er den trådsikker.

Det er vigtigt at bemærke, at behandling af annoteringer ændrer konfigurationen lige før rangering / unmarshalling. Og så - hvis vi kræver, at forekomsten konfigureres on-the-fly ved hjælp af annoteringer, er det generelt en god ide at bruge en separat XStream eksempel for hver tråd.

11. Konklusion

I denne artikel dækkede vi det grundlæggende ved at bruge XStream til at konvertere objekter til XML. Vi lærte også om tilpasninger, vi kan bruge til at sikre, at XML-output opfylder vores behov. Endelig så vi på trådsikkerhedsproblemer med annoteringer.

I den næste artikel i denne serie lærer vi om konvertering af XML til Java-objekter.

Den komplette kildekode til denne artikel kan downloades fra det linkede GitHub-arkiv.


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