2010-03-15 44 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