2012-06-20 16 views
7

JAXB, yazdıklarını okuyamaz gibi görünüyor. Aşağıdaki kodu göz önünde bulundurun:JAXB, arayüzlerin islami olmayan bir listesi değildir

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()); 
} 

Bu elbette basitleştirilmiş bir örnek. Mesele şu ki, bir koleksiyonda çok farklı iki uygulanmış sınıf olan Bar ve Baz'ı saklamak zorundayım. Eh, oldukça benzer bir ortak arayüze sahip olduklarını gözlemledim, bu yüzden bir IFoo arayüzü yarattım ve bunları uygulamak için iki tane yaptım. Şimdi, bu koleksiyonu saklamak ve XML'e yüklemek için araçlara sahip olmak istiyorum. Maalesef bu kod pek işe yaramıyor: koleksiyon kaydedildi, ancak yüklenemedi! amaçlanan çıktı

1 
2 
3 
some xml 
1 
2 
3 

Ama ne yazık ki, gerçek çıktı

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

Anlaşılan, farklı bir şekilde ek açıklamaları kullanmak gerekir olmasıdır? Ya da JAXB'den vazgeçmek ve başka bir şey aramak mı? Ben, marshal için değil, tüm sınıflar için "XMLNode toXML()" yöntemini yazabilirim, ama ...

+0

ait @XmlSeeAlso –

+0

Olası yinelenen kullanımı için belgelerini kontrol edin http://stackoverflow.com/questions/4144296/marshalling Bir arayüz tipinin listesini de soran ve kabul edilen cevapta farklı, çalışan bir yaklaşıma sahip olan, nesne-ile-jaxb nesneleri. –

cevap

8

Aşağıdaki @XmlAnyElement(lax=true)'u deneyin. lax bayrağı, JAXB (JSR-222) uygulamasının öğelere, @XmlRootElement ve @XmlElementDecl ek açıklamalarını temel alarak etki alanı nesnelerine eşleşmesini söyler. Bu olmadan içerikler DOM düğümleri olarak kabul edilir. Ayrıntılı Bilgi İçin

@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); 
    } 
} 

+6

Çalışıyor. Teşekkür ederim! Ama tanrım, bütün bu JAXB şeyleri kara büyü gibidir, henüz üzerinde anlaşılmaz bir rehber buldum. –

+1

@Joker_vD - Java XML & JSON Bağlama bloğumun (http://blog.bdoughan.com/) ve EclipseLink JAXB (MOXy) Kullanım Kılavuzumun (http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy) –

+0

Bu yaklaşımın avantajları ve dezavantajları, aşağıda bağlantılı olan önceki soruya verdiğiniz cevaba verdiğiniz yaklaşımla karşılaştırıldığında nelerdir? (Örneğin, önceki cevap, uygulama kümesinin listeyi tutan sınıf tarafından bilinir olduğunu varsaymaktadır.) Http://stackoverflow.com/a/4145801/202009 –