2009-07-21 10 views
6

У меня возникают проблемы с аннотациями JAXB для поля, которое представляет собой список, чей расширенный тип является интерфейсом. Когда я объявляю это следующим образом:JAXB Аннотации - сопоставление интерфейсов и @XmlElementWrapper

@XmlAnyElement 
private List<Animal> animals; 

Все работает правильно. Но когда я добавить элемент обертки, такие как:

@XmlElementWrapper 
@XmlAnyElement 
private List<Animal> animals; 

Я считаю, что Java правильно объект маршалов, но когда я распаковать документ, созданный сортировочным, мой список пуст. Я опубликовал ниже код, чтобы продемонстрировать эту проблему.

Я делаю что-то неправильно или это ошибка? Я пробовал его с версиями 2.1.12 и 2.2-ea с тем же результатом.

Я работаю через, например, для отображения интерфейсов с аннотациями, расположенных здесь: https://jaxb.dev.java.net/guide/Mapping_interfaces.html

@XmlRootElement 
class Zoo { 

    @XmlElementWrapper 
    @XmlAnyElement(lax = true) 
    private List<Animal> animals; 

    public static void main(String[] args) throws Exception { 
    Zoo zoo = new Zoo(); 
    zoo.animals = new ArrayList<Animal>(); 
    zoo.animals.add(new Dog()); 
    zoo.animals.add(new Cat()); 

    JAXBContext jc = JAXBContext.newInstance(Zoo.class, Dog.class, Cat.class); 
    Marshaller marshaller = jc.createMarshaller(); 

    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    marshaller.marshal(zoo, os); 

    System.out.println(os.toString()); 

    Unmarshaller unmarshaller = jc.createUnmarshaller(); 
    Zoo unmarshalledZoo = (Zoo) unmarshaller.unmarshal(new ByteArrayInputStream(os.toByteArray())); 

    if (unmarshalledZoo.animals == null) { 
     System.out.println("animals was null"); 
    } else if (unmarshalledZoo.animals.size() == 2) { 
     System.out.println("it worked"); 
    } else { 
     System.out.println("failed!"); 
    } 
    } 

    public interface Animal {} 

    @XmlRootElement 
    public static class Dog implements Animal {} 

    @XmlRootElement 
    public static class Cat implements Animal {} 
} 

ответ

1

Это bug, который был исправлен в JAXB 2.1.13. Обновите свои библиотеки или используйте JDK 1.7 или более позднюю версию, и проблема будет решена.

0

Когда я запустить тестовую программу с jdk1.6.0_20 это, кажется, работает, и я получаю следующий результат:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<zoo><animals><dog/><cat/></animals></zoo> 
it worked 
+0

Какая версия JAXB? – codefinger

+0

Я использую версию JAXB 2.1, включенную в jdk1.6.0_20. Вы также можете попробовать свой пример с MOXy JAXB (я технический лидер). Мы исправили ошибку, связанную с вашим вопросом, вам нужно будет использовать сегодняшнюю (4 ноября) или более позднюю версию EclipeseLink 2.2.0: http://www.eclipse.org/eclipselink/downloads/nightly.php –

0

Вы пытались разместить свои аннотации в своих аксессуарах? У меня также была эта проблема с @XmlElementWrapper, но я решил ее решить, поставив аннотацию моего получателя вместо аннотации объявления поля.

8

Если использовать @XmlElementRefs ({ @XmlElementRef (тип = Dog.class), @XmlElementRef (тип = Cat.class)}) частных Список животных;

или использовать @XmlAnyElement (LAX = истина) только, и добавить Dog.class, Cat.class к JAXBContext

0

Когда я запустить тестовую программу с jdk1.6.0_20 она не работает, однако, как только я измененная аннотация для списка от @XmlAnyElement(lax = true) до @XmlElementRefs({ @XmlElementRef(type=Dog.class), @XmlElementRef(type=Cat.class)}), тогда она работает. Не имеет значения, что Dog.class и Cat.class добавлены в JAXBContext или нет.