Может ли JAXB инициализировать значения в базовых классах? - PullRequest
6 голосов
/ 02 декабря 2011

Я работаю над проектом Scala, и мы хотим использовать XML для инициализации наших объектов с помощью JAXB (не Spring).У меня есть иерархия, где больше членов данных добавляются в подклассы.Простой пример будет выглядеть примерно так:

class Animal
{
   string name
}

class Cat extends Animal
{
   int numLives
}

class Dog extends Animal
{
   bool hasSpots
}

Я хотел бы иметь возможность инициализировать список животных из блока XML, который выглядит примерно так:

<Animals>
   <Cat>
      <name>Garfield</name>
      <numLives>9</numLives>
   </Cat>
   <Dog>
      <name>Odie</name>
      <hasSpots>false</hasSpots>
   </Dog>
</Animals>

Какмы бы установили аннотации в классах, чтобы справиться с этим?

Ответы [ 2 ]

3 голосов
/ 02 декабря 2011

В этом примере вы захотите использовать аннотации @XmlElementRef и @XmlRootElement. Это соответствует концепции схемы XML групп замещения. Это позволит вам получить список объектов из иерархии наследования, дифференцированных по элементам.

Животные

Это будет служить корневым объектом для модели предметной области. Он имеет свойство List, помеченное @XmlElementRef. Это означает, что он будет соответствовать значениям на основе значения их @XmlRootElement аннотаций.

package forum8356849;

import java.util.List;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Animals")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Cat.class, Dog.class})
public class Animals {

    @XmlElementRef
    private List<Animal> animals;
}

Animal

package forum8356849;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
class Animal
{
   String name;
}

Cat

Мы будем аннотировать класс Cat аннотацией @XmlRootElement. Используется в тандеме с аннотацией @XmlElementRef на Animals.

package forum8356849;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Cat")
class Cat extends Animal
{
   int numLives;
}

собака

Мы также добавим аннотацию @XmlRootElement к классу Dog.

package forum8356849;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="Dog")
class Dog extends Animal
{
   boolean hasSpots;
}

Демо

Вы можете использовать следующий класс, чтобы увидеть, что все работает как положено. input.xml соответствует XML, указанному в вашем вопросе.

package forum8356849;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Animals.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum8356849/input.xml");
        Animals animals = (Animals) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(animals, System.out);
    }

}

Для получения дополнительной информации

0 голосов
/ 02 декабря 2011

В таких случаях я предпочитаю создавать схему XSD и генерировать из нее код, чтобы вы были в безопасности.Но ответить на ваш вопрос, да, вы можете.Аннотации: XMLElement, XMLAttribute, XMLRootElement.

...