"Inte så snabbt, unge man! Jag har två lektioner till för dig!"

"Två? Wow. Tja, okej. Vad skulle du inte göra för att förstärka din egen coolhet! Jag är helt i öronen."

"XML, liksom JSON, används ofta när data överförs mellan olika program och datorer. Och det finns flera ramverk som avsevärt förenklar livet för Java-programmerare när de arbetar med XML. Idag ska jag presentera dig för ett av dem."

"JAXB är ett utmärkt multifunktionsramverk för att arbeta med XML."

JAXB - 1

"JAXB är en del av JDK, så du behöver inte ladda ner det separat."

"Låt mig först visa dig ett exempel på hur du använder det, och sedan analyserar vi det. Till exempel:"

Konvertera ett objekt till XML
public static void main(String[] args) throws JAXBException
{
 // Create an object to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // And here's the serialization itself:
 marshaller.marshal(cat, writer);

 // Convert everything written to the StringWriter
 String result = writer.toString();
 System.out.println(result);
}
En klass vars objekt konverteras till XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Serialiseringsresultat och skärmutgång:
<cat> 
<name> Missy </name> 
<age> 5 </age> 
<weight> 4 </weight> 
</cat>

"Av någon anledning, rad för rad, påminner den här koden mig om JSON-serialisering. Samma anteckningar, men JSON använde en ObjectMapper, och den här använder Context och Marshaller."

"Japp. De är verkligen väldigt lika. Jackson var modellerad efter JAXB. Men JAXB kopierades också från någonstans. Man kan inte hitta på något genialt från grunden."

"Det verkar så."

"Okej, här är vad som händer:"

"På rad 4-7 skapar vi ett Cat- objekt och fyller det med data."

"På rad 10 skapar vi ett Writer-objekt för att skriva resultatet."

"På rad 13 skapar vi 'kontexten'. Det här liknar ObjectMapper, men sedan skapas ytterligare två underordnade objekt från det. Marshaller är för serialisering och Unmarshaller är för deserialisering. Det finns små skillnader från Jackson, men det är inte inte fundamentalt annorlunda."

"På rad 14 skapar vi ett Marshaller- objekt. Marshalling är en synonym för serialisering."

"På rad 15 satte vi egenskapen FORMATTED_OUTPUT till TRUE. Detta kommer att lägga till radbrytningar och mellanslag till resultatet, så att koden är läsbar för människor och inte bara har all text på en rad."

"På rad 17 serialiserar vi objektet."

"På raderna 20-21 visar vi resultatet av serialiseringen på skärmen."

"Vilka är kommentarerna @XmlType(name = 'cat&') och @XmlRootElement?"

" @XmlRootElement indikerar att det här objektet kan vara 'roten till ett träd' av XML-element. Med andra ord kan det vara elementet på högsta nivån och kan innehålla alla andra element."

" @XmlType(name = 'cat') indikerar att klassen är involverad i JAXB-serialisering, och anger även namnet på XML-taggen för denna klass."

"Okej, nu ska jag visa dig ett exempel på XML-deserialisering:"

Konvertera ett objekt från XML
public static void main(String[] args) throws JAXBException
{
 String xmldata = "<cat><name>Missy</name><age>5</age><weight>4</weight></cat>";
 StringReader reader = new StringReader(xmldata);

 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Unmarshaller unmarshaller = context.createUnmarshaller();

 Cat cat = (Cat) unmarshaller.unmarshal(reader);
}
En klass vars objekt är deserialiserade från XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"Allt är nästan detsamma som med Jackson. Men för säkerhets skull ska jag förklara allt som händer här."

"På rad 3 skickar vi en sträng som lagrar XML som ska deserialiseras."

"På rad 4 lindar vi XML-strängen i en StringReader ."

"På rad 6 skapar vi en JAXB-kontext , till vilken vi skickar listan över klasser."

"På rad 7 skapar vi en Unmarshaller - objektet som kommer att utföra deserialiseringen."

"På rad 9 deserialiserar vi XML från läsarobjektet och får ett Cat-objekt."

"Nu verkar allt nästan självklart. Men för ett par timmar sedan höll jag på med hjärnan för att ta reda på hur det fungerar."

"Det händer alltid när man blir smartare. Komplexa saker blir enkla."

"Jag blir smartare? Jag kan inte annat än att vara glad över det."

"Bra. Här är en lista med kommentarer som du kan använda för att kontrollera resultatet av JAXB-serialisering:"

JAXB-anteckningar Beskrivning
@XmlElement(namn) Placerad nära en åker.
Fältet kommer att lagras i ett XML-element.
Låter dig ställa in taggens namn.
@XmlAttribute(namn) Placerad nära en åker.
Fältet kommer att lagras som ett XML-attribut!
Låter dig ställa in attributets namn.
@XmlElementWrapper(nillable = sant) Placerad nära en åker.
Låter dig ställa in en "wrapper-tagg" för en grupp av element.
@XmlType Placerad nära en klass.
Låter dig ange en metod för att skapa ett objekt om standardkonstruktorn är privat.
@XmlJavaTypeAdapter Placerad nära en åker.
Låter dig ange den klass som ska konvertera fältet till en sträng.

"Vad intressant! Men kan du ge mig ett exempel som använder dessa kommentarer? En förklaring är en sak, men ett fungerande exempel är något annat."

"OK. Jag ska visa dig ett exempel. Jag ville bara tillägga att JAXB låter dig kommentera getter/seter-metoder istället för fält."

"Här är det exemplet jag lovade:"

Konvertera ett objekt till XML
public static void main(String[] args) throws JAXBException
{
 // Create Cat and Zoo objects to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 Zoo zoo = new Zoo();
 zoo.animals.add(cat);
 zoo.animals.add(cat);

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // Here's the serialization itself
 marshaller.marshal(zoo, writer);

 // Convert everything written to the StringWriter into a String
 System.out.println(writer.toString());
}
En klass vars objekt konverteras till XML
@XmlType(name = "zoo")
@XmlRootElement
public class Zoo
{
 @XmlElementWrapper(name = "wild-animals", nillable = true)
 @XmlElement(name = "tiger")
 public List<Cat> animals = new ArrayList<>();
}

public class Cat
{
 @XmlElement(name = "catname")
 public String name;
 @XmlAttribute(name = "age")
 public int age;
 @XmlAttribute(name = "w")
 public int weight;

 public Cat()
 {
 }
}
Serialiseringsresultat och skärmutgång:
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Fröken</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<kattnamn>Fröken </catname> 
</tiger> 
</wild-animals> 
</zoo>

"Lägg märke till att vi den här gången inte serialiserar ett Cat-objekt, utan ett Zoo-objekt som lagrar en samling av Cat-objekt."

"Kattobjektet lades till i samlingen två gånger, så det finns i XML två gånger."

"Samlingen har sin egen " vilda djur "-tagg som omsluter alla samlingens element."

"Ålder- och viktelementen har blivit attributen ålder & w w."

"Med ett @XmlElement- attribut ändrade vi katttaggen till en tigertagg ."

"Var uppmärksam på linje 17. Här skickar vi två klasser ( Zoo och Cat ) till JAXB-kontexten, eftersom de båda är involverade i serialiseringen."

"Idag var en mycket intressant dag. Så mycket ny information."

"Ja. Jag är glad för din skull. Ta nu en kort paus så fortsätter vi."