JAXB不解封接口列表

[英]JAXB doesn't unmarshal list of interfaces


It seems JAXB can't read what it writes. Consider the following code:

JAXB似乎無法讀取它所寫的內容。考慮下面的代碼:

interface IFoo {
    void jump();
}

@XmlRootElement
class Bar implements IFoo {
    @XmlElement
    public String y;

    public Bar() {
        y = "";
    }

    public Bar(String y) {
        this.y = y;
    }

    @Override
    public void jump() {
        System.out.println(y);
    }
}

@XmlRootElement
class Baz implements IFoo {
    @XmlElement
    public int x;

    public Baz() {
        x = 0;
    }

    public Baz(int x) {
        this.x = x;
    }

    @Override
    public void jump() {
        System.out.println(x);
    }
}

@XmlRootElement
public class Holder {
    private List<IFoo> things;

    public Holder() {
        things = new ArrayList<>();
    }

    @XmlElementWrapper
    @XmlAnyElement
    public List<IFoo> getThings() {
        return things;
    }

    public void addThing(IFoo thing) {
        things.add(thing);
    }
}

// ...

try {
    JAXBContext context = JAXBContext.newInstance(Holder.class, Bar.class, Baz.class);

    Holder holder = new Holder();
    holder.addThing(new Bar("1"));
    holder.addThing(new Baz(2));
    holder.addThing(new Baz(3));

    for (IFoo thing : holder.getThings()) {
        thing.jump();
    }

    StringWriter s = new StringWriter();
    context.createMarshaller().marshal(holder, s);

    String data = s.toString();

    System.out.println(data);

    StringReader t = new StringReader(data);
    Holder holder2 = (Holder)context.createUnmarshaller().unmarshal(t);

    for (IFoo thing : holder2.getThings()) {
        thing.jump();
    }
}
catch (Exception e) {
    System.err.println(e.getMessage());
}

It's a simplified example, of course. The point is that I have to store two very differently implemented classes, Bar and Baz, in one collection. Well, I observed that they have pretty similar public interface, so I created an interface IFoo and made them two to implement it. Now, I want to have tools to save and load this collection to/from XML. Unfortunately, this code doesn't quite work: the collection is saved, but then it cannot be loaded! The intended output is

當然,這是一個簡化的例子。重點是,我必須在一個集合中存儲兩個非常不同的實現類,Bar和Baz。我觀察到它們有非常相似的公共接口,所以我創建了一個接口IFoo,並讓它們兩個來實現它。現在,我想要一些工具來保存和加載這個集合到/從XML。不幸的是,這段代碼不能正常工作:保存了集合,但是不能加載它!預期的輸出

1
2
3
some xml
1
2
3

But unfortunately, the actual output is

但不幸的是,實際輸出是

1
2
3
some xml
com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to testapplication1.IFoo

Apparently, I need to use the annotations in a different way? Or to give up on JAXB and look for something else? I, well, can write "XMLNode toXML()" method for all classes I wan't to (de)marshal, but...

顯然,我需要以不同的方式使用注釋?或者放棄JAXB,尋找其他東西?我可以為我不想編組的所有類編寫“XMLNode toXML()”方法,但是…

1 个解决方案

#1


8  

Try the following @XmlAnyElement(lax=true). The lax flag tells the JAXB (JSR-222) implementation to match elements to domain objects based their @XmlRootElement and @XmlElementDecl annotations. Without it the contents are treated as DOM nodes.

試試以下@XmlAnyElement(寬松= true)。lax標志告訴JAXB (JSR-222)實現根據其@XmlRootElement和@XmlElementDecl注釋將元素匹配到域對象。沒有它,內容將被視為DOM節點。

@XmlRootElement
public class Holder {
    private List<IFoo> things;

    public Holder() {
        things = new ArrayList<>();
    }

    @XmlElementWrapper
    @XmlAnyElement(lax=true)
    public List<IFoo> getThings() {
        return things;
    }

    public void addThing(IFoo thing) {
        things.add(thing);
    }
}

For More Information

的更多信息


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2012/06/20/725019c9cccaa77038b9297c04891214.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com