Осталось еще несколько интересных вещей в JAXB, первое это тег @XmlSeeAlso(), он применяется
при наследовании от абстракного класса или когда вы работаете с интерфейсами.
Если вы задействуете тег в интерфейсе или абстрактном классе, то при этом вам
не придется описывать все зависимости в JAXB контексте, т.е. не нужно
будет описывать его в методе при создании контекста JAXBContext.newInstance(…);.
Давайте я вам все поясню на примере, напишем для начала наш абстрактный класс:
package com.vit.fly;
import
javax.xml.bind.annotation.XmlElement;
import
javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public abstract class Vit6 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Потом
можно написать множество классов которые наследуются от нашего абстракного
класса Vit6.class, нам для примера хватит одного:
package com.vit.fly;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Vit7 extends Vit6 {
@Override
public void setName(String name) {
super.setName(name);
}
}
Далее нам
нужно написать класс который использует наш абстрактый класс Vit6.class:
package com.vit.fly;
import
javax.xml.bind.annotation.XmlRootElement;
import
javax.xml.bind.annotation.XmlSeeAlso;
@XmlRootElement()
@XmlSeeAlso(value = {Vit7.class})
public class Vit8 {
private Vit6 v;
public Vit6 getV() {
return v;
}
public void setV(Vit6 v) {
this.v = v;
}
}
В
аннотации @XmlSeeAlso(value = {Vit7.class}) мы говорим, что можно использовать реализацию
класса Vit7.class, замете что он у нас не
описан в контексте JAXBContext.newInstance(Vit8.class).
взглянем на программу:
public class MainVit1 {
static public void main(String args[]) {
Vit6 vit6 = new Vit7(); vit6.setName("Lopanov");
Vit8 vit8 = new Vit8(); vit8.setV(vit6);
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Vit8.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
marshaller.marshal(vit8, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Смотрим на вывод программы:
<?xml version="1.0"
encoding="UTF-8" standalone="yes"?>
<vit8>
<v xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="vit7">
<name>Lopanov</name>
</v>
</vit8>
Давайте
познакомимся с двумя аннотациями которые позволяют нам работать с бинарнами
данными, первая из них это аннотация @XmlInlineBinaryData(), которая
применяется к массиву байт и он кодируется в
xml файле как
тип xs:base64Binary. Вторая аннотация @XmlMimeType(value =
"image/jpeg") применяется к типам данных java.awt.Image или
javax.xml.transform.Source, которые так же приобразуются к типу xs:base64Binary. Расмотрим простой пример, в котором одно поле
представляет из себя массив байт. Создадим
класс Vit9 с полем типа byte[]:
package
com.vit.fly;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Vit9 {
//@XmlMimeType(value = "image/jpeg")
@XmlInlineBinaryData
private byte[] data;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
Напишем
программу для запуска нашего примера, закодируем фразу "Hello JAXB" в байты:
package com.vit.fly;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class MainVit3 {
public static void main(String args[]) throws JAXBException {
Vit9 Data = new Vit9();
Data.setData("Hello
JAXB".getBytes()); //encoded
in xs:base64Binary by default
JAXBContext context = JAXBContext.newInstance(Vit9.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(Data, System.out);
}
}
В итоге
получим в выводе base64 закодированное значение фразы "Hello JAXB":
<?xml version="1.0"
encoding="UTF-8" standalone="yes"?>
<vit9>
<data>SGVsbG8gSkFYQg==</data>
</vit9>
По
умолчанию если поле имеет null значение, то оно не отображается в xml файле посредством тега, для вывода пустого
тега нужно в аннотации выставить значение nillable в true. И так расмотрим
предыдуший пример и закоментируем в программе строчку Data.setData("Hello JAXB".getBytes()):
import javax.xml.bind.Marshaller;
public class MainVit3 {
public static void main(String args[]) throws JAXBException {
Vit9 Data = new Vit9();
//Data.setData("Hello
JAXB".getBytes()); //encoded
in xs:base64Binary by default
JAXBContext context = JAXBContext.newInstance(Vit9.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(Data, System.out);
}
}
Получим вывод:
<?xml version="1.0"
encoding="UTF-8" standalone="yes"?>
<vit9/>
Добавим в
классе Vit9 аннотацию @XmlElement(nillable = true) :
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Vit9 {
@XmlInlineBinaryData
@XmlElement(nillable = true)
private byte[] data;
…..
}
Получим
вывод тега, даже если значение null:
<?xml version="1.0" encoding="UTF-8"
standalone="yes"?>
<vit9>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:nil="true"/>
</vit9>
Комментариев нет:
Отправить комментарий