2010-03-15 47 views
4

我構建了以下情況。所有JAXBLists接口:使用JAXB解組/編組列表<String> - 繼承

public interface JaxbList<T> { 
public abstract List<T> getList(); 
} 

而一個基本實現:

@XmlRootElement(name="list") 
public class JaxbBaseList<T> implements JaxbList<T>{ 
    protected List<T> list; 

    public JaxbBaseList(){} 

    public JaxbBaseList(List<T> list){ 
     this.list=list; 
    } 

    @XmlElement(name="item") 
    public List<T> getList(){ 
     return list; 
    } 
} 

以及針對URI列表的實現:

@XmlRootElement(name="uris") 
public class JaxbUriList2 extends JaxbBaseList<String> { 

    public JaxbUriList2() { super(); } 
    public JaxbUriList2(List<String> list){ 
     super(list); 
    } 


    @Override 
    @XmlElement(name="uri") 
    public List<String> getList() { 
     return list; 
    } 
} 

而且我使用的列表通過以下方式:

public JaxbList<String> init(@QueryParam("amount") int amount){ 

     List<String> entityList = new Vector<String>(); 
     ... 
     enityList.add("http://uri"); 
    ... 
     return new JaxbUriList2(entityList); 
    } 

我想輸出應該是:

<uris> 
<uri> 
http://uri 
</uri> 
... 
</uris> 

但它是這樣的:

<uris> 
<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string"> 
http://uri 
</item> 
... 
<uri> 
http://uri 
</uri> 
... 
</uris> 

我認爲這是與繼承,但我不明白這一點...

有什麼問題? - 我該如何解決它?

在此先感謝!

回答

2

註解是通過反思獲得的。註釋綁定到它定義的類型。

public class AnnotationTest { 

    public static class A 
    { 
     @XmlElement(name="item") 
     public void doIt() { } 
    } 

    public static class B extends A 
    { 
     @XmlElement(name="name") 
     public void doIt() { } 
    } 

    public static void main(String[] args) 
    { 
     B b = new B(); 
     Method m = b.getClass().getMethods()[0]; 
     Annotation[] ann = m.getDeclaredAnnotations(); 
     System.out.println(ann.length ); // prints 1 
    } 
} 

所以這種行爲並不是由於反射機制本身。看起來JAXB框架似乎明確列出了超類中類中方法的註釋。令人驚訝的是,這仍然有效,但不是你想要的。

難道你不能只刪除基類中的@XmlElement(name="item")

編輯

根據您的意見(但仍然不知道如果我所有的正確理解),我建議:

@XmlRootElement(name="list") 
public class JaxbBaseList<T> implements JaxbList<T>{ 
    protected List<T> list; 

    public List<T> getList(){ 
     return list; 
    } 
} 


public class JaxbPrimitiveList<T> extends JaxbList<T>{ 
    protected List<T> list; 

    @XmlElement(name="item") 
    public List<T> getList(){ 
     return list; 
    } 
} 

@XmlSeeAlso(Uri) 
public class JaxbUriList<Uri> extends JaxbList<Uri>{ 
    protected List<Uri> list; 

    @XmlElement(name="uri") 
    public List<Uri> getList(){ 
     return list; 
    } 
} 
+0

的問題是,該JaxbBaseList應該用於語言類型Long,Integer,String等,其他實現應該用於其他類型。所以JaxbUriList2只是一個令人迷惑的例子,更好的是我使用了URI而不是String。那麼我們需要@XmlSeeAlso註釋。 所以我需要兩個類,因爲它們是。用於語言類型的JaxbBaseList和用於使用@XmlSeeAlso註釋實現的所有其他類型,即: 「@XmlSeeAlso(URI.class)public class JaxbUriList extends JaxbBaseList 」。 – gerry 2010-03-15 13:34:49

+0

關於你的編輯。好的,那是有效的。但是JaxbBaseList 和JaxbPrimitiveList 是相同的,只有JaxbPrimitiveList中的@XmlElement(name =「item」)除外。這不符合DRY的概念。是的,好吧,不是JaxbUriList ;但我不能想到的解決方案。 重複一遍,我的問題是「爲什麼重寫了@XmlRootElement(name =」list「)註釋的名稱,而不是@XmlElement(name =」item「)?爲什麼列表添加了兩次:一次作爲'項目'和一次'Uri'?「 – gerry 2010-03-15 17:15:30

+0

我知道這不是你最初的問題的答案。我只是想弄清楚自己究竟是反射機制還是JAXB的錯誤。關於你的問題,這就是JAXB的實現方式,我擔心答案因此就像「因爲它是這樣的」。但是也許有人會提供更令人信服的答案來解釋JAXB實現的基本原理和/或不一致之處。 – ewernli 2010-03-15 18:04:26