— Так вот. Как ты уже, наверное, догадался — это еще не все.
Сейчас я тебе расскажу об еще нескольких аспектах JAXB. Но начнем мы, как и в случае с JSON, с коллекций.
При десериализации коллекций в JAXB тоже возникает неопределенность, какую именно коллекцию (ArrayList, LinkedList, Vector, …) подставить в переменную типа List? И опять ответ на этот вопрос дают аннотации.
Тут все довольно просто. Если тип коллекции не задан в аннотации к ней, тогда JAXB попробует подобрать самую подходящую коллекцию – на основе типа. Для List это будет ArrayList, для Map – HashMap и т.д.
На самом деле тут гораздо меньше проблем, чем в случае с JSON, т.к. у каждого класса есть его уникальный тэг, а по тэгу можно точно определить – что это за класс.
Например, если надо десериализовать группу элементов, которые унаследованы от общего предка, для этого используется аннотация @XmlAny:
public static void main(String[] args) throws JAXBException
{
String xmldata = "<zoo><cat/><cat/><dog/><cat/></zoo>";
StringReader reader = new StringReader(xmldata);
JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class, Dog.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Zoo zoo = (Zoo) unmarshaller.unmarshal(reader);
}
@XmlType(name = "zoo") @XmlRootElement class Zoo { @XmlAnyElement public List<Object> animals; } @XmlType(name = "cat") @XmlRootElement class Cat { public String name; public int age; public int weight; Cat() { } } @XmlType(name = "dog") @XmlRootElement class Dog { public String name; public int age; public int weight; Dog() { } }
Если коллекция помечена аннотацией @XmlAnyElement, то в нее могут быть помещены любые подходящие объекты. JAXB Unmarshaller при этом обращает внимание на тэги.
При этом последовательность тэгов «<zoo><cat/><cat/><dog/><cat/></zoo>» будет превращена в набор объектов Cat, Cat, Dog, Cat.
— Ожидаемо, в общем.
— Ага. О, кстати, вот еще что. Если ты десериализуешь смесь текста и тэгов, для этого надо использовать аннотацию @XmlMixed.
Пример такого XML:
<data> <items> test 1 <item/> text 2 <item> name </item> text 3 </items> </data>
— Ого. А я и забыл, что такой XML бывает. Привык, что все так красиво, тэги вложены, все дела.
— Бывает. И даже на этот случай у JAXB есть аннотация!
— Отлично. А я вот, кстати, хотел спросить, а как сериализуются enum?
— Хороший вопрос! Молодец! Я-то как раз упустил эту тему.
Для enum существует специальная аннотация @XmlEnum, которой надо помечать enum. В ней же можно указать – будут значения представлены в виде чисел или строк.
Также есть специальная аннотация @XmlEnumValue, которая позволяет задать специальное значение, которое будет соответствовать данному значению enum’а.
Примеры:
Числа | Строки |
---|---|
|
|
— Ух ты. Не могу представить, где мне это может понадобиться, но думаю, что это очень полезная штука. А главное – не обязательно придерживается стандартных строковых или числовых значений.
— Ага. Это полезно, когда ты, например, пишешь программу, которая обменивается сообщениями, скажем, с сервером Facebook, и у них свой заданный набор значений. Тебе достаточно просто прописать их у своего enum и все заработает.
— Это же замечательно. Мне определенно нравится JAXB.
— Отлично. Тогда на сегодня все. Иди — отдыхай.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ