I've build the following case. An interface for all JAXBLists:
public interface JaxbList<T> {
public abstract List<T> getList();
}
And an base implementation:
@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;
}
}
As well as an implementation for a list of URIs:
@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;
}
}
And I'm using the List in the following way:
public JaxbList<String> init(@QueryParam("amount") int amount){
List<String> entityList = new Vector<String>();
...
enityList.add("http://uri");
...
return new JaxbUriList2(entityList);
}
I thought the output should be:
<uris>
<uri>
http://uri
</uri>
...
</uris>
But it is something like this:
<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
<开发者_StackOverflow社区/uri>
...
</uris>
I think it has something to do with the inheritance, but I don't get it...
What's the problem? - How can I fix it?
Thanks in advance!
Annotations are obtained through reflection. The annotation is bound to the type it's defined in.
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
}
}
So this behavior is not due to the reflection mechanism itself. It seems like the JAXB framework does explicitly list the annotation on the method in the class and the super classes. Surprisingly this still works, but not as you would like.
Can't you just remove @XmlElement(name="item")
in the base class?
EDIT
According to your comment (but still not sure if I understand all correctly), I would suggest:
@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;
}
}
精彩评论