已婚女人梦见自己再婚:JAXB Annotations - Mapping interfaces and @XmlElementWrapper

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 18:04:49

up vote2down votefavoriteshare [fb]share [tw]

I am having trouble with JAXB annotations for a field that is a list whose generified type is an interface. When I have it declared such as:

@XmlAnyElement
private List animals;

Every thing works correctly. But when I add a wrapper element, such as:

@XmlElementWrapper
@XmlAnyElement
private List animals;

I find that the Java object marshals correctly, but when I unmarshal the document created by marshaling, my list is empty. I have posted below the code to demonstrate this problem.

Am I doing something wrong, or is this a bug? I have tried it with version 2.1.12 and 2.2-ea with the same result.

I am working through the example for mapping interfaces with annotations located here:https://jaxb.dev.java.net/guide/Mapping_interfaces.html

@XmlRootElement
class Zoo {

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

public static void main(String[] args) throws Exception {
Zoo zoo = new Zoo();
zoo.animals = new ArrayList();
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 {}
}
interface annotations jaxblink|improve this questionasked Jul 21 '09 at 13:26joekutner
623311
86% accept rate
feedback

4 Answers

activeoldestvotesup vote2down vote

Should use @XmlElementRefs({ @XmlElementRef(type=Dog.class), @XmlElementRef(type=Cat.class)}) private List animals;

or use @XmlAnyElement(lax = true) only, and add Dog.class, Cat.class to JaxbContext

link|improve this answeranswered Feb 28 at 14:49Golyo
212
feedbackup vote0down vote

When I run your test program with jdk1.6.0_20 it appears to work and I get the following output:



it worked
link|improve this answeranswered Jul 29 '10 at 13:26Blaise Doughan
18k31426

What version of JAXB? – joekutner Nov 4 '10 at 19:41
I'm used the version of JAXB 2.1 included with jdk1.6.0_20. You can also try your example with MOXy JAXB (I'm the tech lead). We fixed a bug related to your question, you will need to use today's (Nov 4) or later EclipeseLink 2.2.0 nightly download: eclipse.org/eclipselink/downloads/nightly.php – Blaise Doughan Nov 4 '10 at 20:00feedbackup vote0down vote

Have you tried putting your annotations in your accessories? I also had this problem with @XmlElementWrapper before but i got it solved by putting the annotating my getter instead of annotating the field declaration.

link|improve this answeranswered Dec 20 '10 at 2:48ely
111
feedbackup vote0down vote

When I run your test program with jdk1.6.0_20 it does not work, however one I changed annotation forlist from @XmlAnyElement(lax = true) to @XmlElementRefs({ @XmlElementRef(type=Dog.class), @XmlElementRef(type=Cat.class)}) then it works it does not matter that dog.class and cat.class are added to JAXBContext or not

link|improve this answeranswered Sep 12 at 18:17frank
1

(###)