2012-03-29 38 views
6

所以我试图编组对象的通用列表,但我希望每个列表都有一个特定的XmlRootElement(name ..)。我这样做的方式,我知道,如果不为每种类型的对象编写一个特定的包装类并声明XmlRootElement,就不太可能。但也许有另一种方式...?JAXB编组泛型变量根元素名称列表

考虑下面的类:

abstract public class Entity { 

} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name="user") 
public class User extends Entity { 

    private String username; 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

} 

@XmlRootElement 
public class EntityList<T extends Entity> { 

    @XmlAnyElement(lax=true) 
    private List<T> list = new ArrayList<T>(); 

    public void add(T entity) { 
     list.add(entity); 
    } 

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

} 


public class Test { 

    public static void main(String[] args) throws JAXBException { 

     User user1 = new User(); 
     user1.setUsername("user1"); 

     User user2 = new User(); 
     user2.setUsername("user2"); 

     EntityList<User> list = new EntityList<User>(); 
     list.add(user1); 
     list.add(user2); 

     JAXBContext jc = JAXBContext.newInstance(EntityList.class, User.class); 
     Marshaller m = jc.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.marshal(list, System.out); 
    } 

} 

正如预期的那样,这将产生:

<entityList> 
    <user> 
     <username>user1</username> 
    </user> 
    <user> 
     <username>user2</username> 
    </user> 
</entityList> 

什么,我要的是能够修改标签名称,这取决于我创建实体的类型EntityList与。

我知道我们在说这里的编译和运行时间,但也许有某种哈克的方式来改变父子元素包装从孩子?

回答

3

您可以将EntityList的实例包装到JAXBElement中以在运行时提供根元素名称。

+0

感谢您指出我在这个方向...这是一个简单的例子,因为我使用Spring的MarshallingView为JAXB编组。但在知道我可以在运行时使用JAXBElement作为包装器的情况下,我可以编写自己的编组器,并在运行时反编译自定义注释。谢谢! – user1301841 2012-03-29 22:07:08