XStream brukerhåndbok: Konvertering av objekter til XML

1. Oversikt

I denne opplæringen lærer vi hvordan du bruker XStream-biblioteket til å serieisere Java-objekter til XML.

2. Funksjoner

Det er ganske mange interessante fordeler ved å bruke XStream til å serialisere og deserialisere XML:

  • Konfigurert riktig produserer den veldig ren XML
  • Gir betydelige muligheter for tilpasning av XML-utdata
  • Støtte for objektgrafer, inkludert sirkulære referanser
  • For de fleste brukstilfeller er XStream-forekomsten trådsikker, en gang konfigurert (det er advarsler når du bruker merknader)
  • Tydelige meldinger blir gitt under avvikshåndtering for å diagnostisere problemer
  • Fra og med versjon 1.4.7 har vi det sikkerhetsegenskaper tilgjengelig for å ikke tillate serialisering av visse typer

3. Prosjektoppsett

For å bruke XStream i prosjektet vårt vil vi legge til følgende Maven-avhengighet:

 com.thoughtworks.xstream xstream 1.4.9 

4. Grunnleggende bruk

De XStream klasse er en fasade for API. Når du oppretter en forekomst av XStream, må vi også ta vare på trådsikkerhetsproblemer:

XStream xstream = ny XStream ();

Når en forekomst er opprettet og konfigurert, kan den deles på tvers av flere tråder for marshalling / unmarshalling med mindre du aktiverer behandling av merknader.

4.1. Drivere

Flere drivere støttes, som f.eks DomDriver, StaxDriver, XppDriver, og mer. Disse driverne har forskjellige ytelses- og ressursbrukskarakteristikker.

XPP3-driveren brukes som standard, men selvfølgelig kan vi enkelt endre driveren:

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

4.2. Genererer XML

La oss starte med å definere en enkel POJO for - Kunde:

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

La oss nå generere en XML-representasjon av objektet:

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

Ved å bruke standardinnstillingene produseres følgende utdata:

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

Fra denne utgangen kan vi tydelig se at den inneholder koden bruker det fullt kvalifiserte klassenavnet på Kunde som standard.

Det er mange grunner til at vi kan bestemme at standardadferden ikke passer til våre behov. Vi kan for eksempel ikke være komfortable med å avsløre pakkestrukturen til applikasjonen vår. Dessuten er XML-generert betydelig lenger.

5. Aliaser

An alias er et navn vi ønsker å bruke for elementer i stedet for å bruke standardnavn.

For eksempel kan vi erstatte com.baeldung.pojo.Kunde med kunde ved å registrere et alias for Kunde klasse. Vi kan også legge til aliaser for egenskaper til en klasse. Ved å bruke aliaser kan vi gjøre XML-utdataene våre mye mer lesbare og mindre Java-spesifikke.

5.1. Klassealiaser

Aliaser kan registreres enten programmatisk eller ved å bruke merknader.

La oss nå kommentere vår Kunde klasse med @XStreamAlias:

@XStreamAlias ​​("kunde")

Nå må vi konfigurere forekomsten vår for å bruke denne merknaden:

xstream.processAnnotations (Customer.class);

Alternativt, hvis vi ønsker å konfigurere et alias programmatisk, kan vi bruke koden nedenfor:

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

Enten du bruker alias eller programmatisk konfigurasjon, vil utgangen for en Kunde objektet vil være mye renere:

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

5.2. Feltaliaser

Vi kan også legge til aliaser for felt ved å bruke den samme merknaden som brukes for aliasingsklasser. For eksempel hvis vi ønsket feltet fornavn som skal erstattes med fn i XML-representasjonen kan vi bruke følgende kommentar:

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

Alternativt kan vi oppnå det samme målet programmatisk:

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

De aliasField metoden godtar tre argumenter: aliaset vi ønsker å bruke, klassen som egenskapen er definert i, og eiendomsnavnet vi ønsker å alias.

Uansett hvilken metode som brukes, er utgangen den samme:

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

5.3. Standardaliaser

Det er flere alias som er forhåndsregistrert for klasser - her er noen av disse:

alias ("float", Float.class); alias ("date", 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

Nå skal vi legge til en liste over Kontaktinformasjon inne i Kunde klasse.

privat liste contactDetailsList;

Med standardinnstillinger for samlehåndtering er dette resultatet:

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

La oss anta at vi må utelate contactDetailsList foreldrekoder, og vi vil bare ha hver Kontaktinformasjon element for å være et barn av kunde element. La oss endre eksemplet vårt igjen:

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

Nå, når XML genereres, blir rotkodene utelatt, noe som resulterer i XML nedenfor:

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

Det samme kan også oppnås ved å bruke merknader:

@XStreamImplicit privat liste contactDetailsList;

7. Omformere

XStream bruker et kart over Konverter tilfeller, hver med sin egen konverteringsstrategi. Disse konverterer leverte data til et bestemt format i XML og tilbake igjen.

I tillegg til å bruke standardomformerne, kan vi endre standardinnstillingene eller registrere egendefinerte omformere.

7.1. Endre en eksisterende omformer

Anta at vi ikke var fornøyd med måten dob tagger ble generertved hjelp av standardinnstillingene. Vi kan endre den tilpassede omformeren for Dato levert av XStream (DateConverter):

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

Ovennevnte vil gi produksjonen i “dd-MM-åååå”Format:

 John Doe 14-02-1986 

7.2. Egendefinerte omformere

Vi kan også lage en tilpasset omformer for å oppnå samme utgang som i forrige avsnitt:

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

Til slutt registrerer vi vår MyDateConverter klasse som nedenfor:

xstream.registerConverter (ny MyDateConverter ());

Vi kan også lage omformere som implementerer SingleValueConverter grensesnitt, som er designet for å 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 (Object obj) {SimpleDateFormat formatter = new SimpleDateFormat ("dd-MM-åååå"); Dato dato = ((kunde) obj) .getDob (); return ((Customer) obj) .getFirstName () + "," + ((Customer) obj) .getLastName () + "," + formatter.format (date); } // andre metoder}

Til slutt registrerer vi oss MySingleValueConverter:

xstream.registerConverter (ny MySingleValueConverter ()); 

Ved hjelp av MySingleValueConverter, XML-utgangen for en Kunde er som følgende:

John, Doe, 14-02-1986

7.3. Konverteringsprioritet

Ved registrering Konverter objekter, er det også mulig å angi prioritetsnivå.

Fra XStream-javadocs:

Omformerne kan registreres med en eksplisitt prioritet. Som standard er de registrert hos XStream.PRIORITY_NORMAL. Omformere med samme prioritet vil bli brukt i omvendt rekkefølge de er registrert. Standardomformeren, dvs. omformeren som skal brukes hvis ingen annen registrert omformer er egnet, kan registreres med prioritet XStream.PRIORITY_VERY_LOW. XStream bruker som standard ReflectionConverter som reservekonverterer.

API-en gir flere navngitte prioritetsverdier:

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

8.Utelater felt

Vi kan utelate felt fra den genererte XML-en vår ved hjelp av enten merknader eller programmatisk konfigurasjon. For å utelate et felt ved hjelp av en kommentar, bruker vi bare @XStreamOmitField kommentar til det aktuelle feltet:

@XStreamOmitField privat streng fornavn;

For å utelate feltet programmatisk, bruker vi følgende metode:

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

Uansett hvilken metode vi velger, er utgangen den samme:

 Doe 14-02-1986 

9. Attributtfelt

Noen ganger kan det være lurt å serieisere et felt som attributt til et element i stedet for som selve elementet. Anta at vi legger til en contactType felt:

private String contactType;

Hvis vi vil sette contactType som et XML-attributt, kan vi bruke @XStreamAsAttribute kommentar:

@XStreamAsAttribute private String contactType; 

Alternativt kan vi oppnå det samme målet programmatisk:

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

Resultatet av en av metodene ovenfor er det samme:

 6673543265 0124-2460311 

10. Samtidighet

XStreams behandlingsmodell gir noen utfordringer. Når forekomsten er konfigurert, er den trådsikker.

Det er viktig å merke seg at behandling av merknader endrer konfigurasjonen like før rangering / unmarshalling. Og så - hvis vi krever at forekomsten konfigureres on-the-fly ved hjelp av merknader, er det generelt lurt å bruke en separat XStream forekomst for hver tråd.

11. Konklusjon

I denne artikkelen dekket vi det grunnleggende om å bruke XStream til å konvertere objekter til XML. Vi lærte også om tilpasninger vi kan bruke for å sikre at XML-utdata oppfyller våre behov. Til slutt så vi på trådsikkerhetsproblemer med merknader.

I neste artikkel i denne serien vil vi lære om konvertering av XML til Java-objekter.

Den komplette kildekoden for denne artikkelen kan lastes ned fra det koblede GitHub-depotet.


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