"Не толкова бързо, младежо! Имам още два урока за теб!"

„Две? Уау. Е, добре. Какво не бихте направor, за да подобрите собственото си хладнокръвие! Цял съм в ушите.“

"XML, подобно на JSON, често се използва при предаване на данни между различни програми и компютри. И има няколко рамки, които значително опростяват живота на Java програмистите при работа с XML. Днес ще ви запозная с една от тях."

„JAXB е отлична многофункционална рамка за работа с XML.“

JAXB - 1

„JAXB е част от JDK, така че не е необходимо да го изтегляте отделно.“

„Нека първо ви покажа пример How да го използвате и след това ще го анализираме. Например:“

Преобразувайте обект в 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);
}
Клас, чиито обекти се конвертират в XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Резултат от сериализация и екранен изход:
<котка> 
<име > Миси </ име 
> <възраст> 5 </възраст> 
<тегло > 4 < /тегло> < 
/котка>

„По няHowва причина, ред по ред, този code ми напомня за JSON сериализация. Същите анотации, но JSON използва ObjectMapper, а това използва Context и Marshaller.“

"Да. Те наистина са много сходни. Джаксън е моделиран след JAXB. Но JAXB също е копиран отнякъде. Не можете да измислите нещо гениално от нулата."

— Изглежда така.

„Добре, ето Howво се случва:“

„В редове 4-7 създаваме обект Cat и го попълваме с данни.“

„В ред 10 създаваме обект Writer, за да напишем резултата.“

„В ред 13 създаваме „контекста“. Това е подобно на ObjectMapper, но след това от него се създават два допълнителни дъщерни обекта. Marshaller е за сериализация, а Unmarshaller е за десериализация. Има малки разлики с Jackson, но не не е коренно различен."

„В ред 14 създаваме обект Marshaller . Marshalling е синоним на сериализация.“

„В ред 15 задаваме свойството FORMATTED_OUTPUT на TRUE. Това ще добави нови редове и интервали към резултата, така че codeът да е четим от хора и да не съдържа целия текст само на един ред.“

„В ред 17 ние сериализираме обекта.“

„В редове 20-21 показваме резултата от сериализацията на екрана.“

„Какви са анотациите @XmlType(name = 'cat&') и @XmlRootElement?“

" @XmlRootElement показва, че този обект може да бъде "корен на дърво" на XML елементи. С други думи, той може да бъде елемент от най-високо ниво и може да съдържа всички други елементи."

" @XmlType(name = 'cat') показва, че класът участва в сериализацията на JAXB и също така указва името на XML тага за този клас."

„Добре, сега ще ви покажа пример за XML десериализация:“

Конвертиране на обект от 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);
}
Клас, чиито обекти са десериализирани от XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"Всичко е почти същото като с Джаксън. Но за всеки случай ще обясня всичко, което се случва тук."

„В ред 3 предаваме низ , който съхранява XML, който трябва да бъде десериализиран.“

„В ред 4 обвиваме XML низа в StringReader .“

„В ред 6 създаваме JAXB контекст , към който предаваме списъка с класове.“

„В ред 7 създаваме Unmarshaller обектът, който ще извърши десериализацията.“

„В ред 9 десериализираме XML от обекта за четене и получаваме обект Cat.“

„Сега всичко изглежда почти очевидно. Но преди няколко часа си натоварих мозъка, за да разбера How работи.“

"Това винаги се случва, когато станеш по-умен. Сложните неща стават прости."

"Ставам по-умен? Не мога да не се радвам за това."

„Страхотно. Тогава ето списък с анотации, които можете да използвате, за да контролирате резултата от JAXB сериализацията:“

JAXB анотации Описание
@XmlElement(име) Поставен в близост до поле.
Полето ще бъде съхранено в XML елемент.
Позволява ви да зададете името на етикета.
@XmlAttribute(име) Поставен в близост до поле.
Полето ще бъде съхранено като XML атрибут!
Позволява ви да зададете името на атрибута.
@XmlElementWrapper(nillable = true) Поставен в близост до поле.
Позволява ви да зададете „маркер за обвивка“ за група елементи.
@XmlType Поставен в близост до клас.
Позволява ви да посочите метод за създаване на обект, ако конструкторът по подразбиране е частен.
@XmlJavaTypeAdapter Поставен в близост до поле.
Позволява ви да посочите класа, който ще преобразува полето в низ.

„Колко интересно! Но можете ли да ми предоставите пример, който използва тези анотации? Обяснението е едно, но работещият пример е нещо друго.“

„ОК. Ще ви покажа пример. Просто исках да добавя, че JAXB ви позволява да коментирате методи за получаване/настройка instead of полета.“

„Ето примера, който обещах:“

Преобразувайте обект в 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());
}
Клас, чиито обекти се конвертират в 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()
 {
 }
}
Резултат от сериализация и екранен изход:
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Миси</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<catname>Миси </catname> 
</tiger> 
</wild-animals> 
</zoo>

„Забележете, че този път не сериализираме обект Cat, а обект Zoo, който съхранява колекция от обекти Cat.“

„Обектът котка беше добавен към колекцията два пъти, така че е в XML два пъти.“

„Колекцията има свой собствен етикет „ диви животни “, който обвива всички елементи на колекцията.“

„ Елементите за възраст и тегло се превърнаха в атрибути за възраст и тегло .“

„Използвайки атрибут @XmlElement , сменихме котешкото етикетче на тигърско етикетче .“

„Обърнете внимание на ред 17. Тук предаваме два класа ( Zoo и Cat ) към JAXB контекста, тъй като и двата са включени в сериализацията.“

„Днес беше много интересен ден. Толкова много нова информация.“

"Да. Радвам се за вас. Сега си направете кратка почивка и ще продължим."