JAXB 可以在基类中初始化值吗?
Posted
技术标签:
【中文标题】JAXB 可以在基类中初始化值吗?【英文标题】:Can JAXB initialize values in base classes? 【发布时间】:2012-01-11 12:18:58 【问题描述】:我正在处理一个 Scala 项目,我们希望使用 XML 来通过 JAXB(不是 Spring)初始化我们的对象。我有一个层次结构,在子类中添加了更多数据成员。一个简单的示例如下所示:
class Animal
string name
class Cat extends Animal
int numLives
class Dog extends Animal
bool hasSpots
我希望能够从如下所示的 XML 块初始化动物列表:
<Animals>
<Cat>
<name>Garfield</name>
<numLives>9</numLives>
</Cat>
<Dog>
<name>Odie</name>
<hasSpots>false</hasSpots>
</Dog>
</Animals>
我们将如何设置类中的注释来处理这个问题?
【问题讨论】:
【参考方案1】:在这种情况下,我更喜欢创建 XSD 架构并从中生成代码,这样您就安全了。 但要回答你的问题,是的,你可以。注释是 XMLElement、XMLAttribute、XMLRootElement。
【讨论】:
【参考方案2】:对于本示例,您将需要使用 @XmlElementRef
和 @XmlRootElement
注释。这对应于替换组的 XML 模式概念。这将允许您拥有一个按元素区分的继承层次结构中的对象列表。
动物
这将作为域模型的根对象。它有一个带有@XmlElementRef
注释的List
属性。这意味着它将根据 @XmlRootElement
注释的值匹配值。
package forum8356849;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Animals")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(Cat.class, Dog.class)
public class Animals
@XmlElementRef
private List<Animal> animals;
动物
package forum8356849;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
class Animal
String name;
猫
我们将使用@XmlRootElement
注释来注释Cat
类。这与Animals
上的@XmlElementRef
注释一起使用。
package forum8356849;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Cat")
class Cat extends Animal
int numLives;
狗
我们还将在Dog
类中添加一个@XmlRootElement
注释。
package forum8356849;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Dog")
class Dog extends Animal
boolean hasSpots;
演示
您可以使用以下类来查看一切是否按预期工作。 input.xml
对应于您问题中提供的 XML。
package forum8356849;
import java.io.File;
import javax.xml.bind.*;
public class Demo
public static void main(String[] args) throws Exception
JAXBContext jc = JAXBContext.newInstance(Animals.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum8356849/input.xml");
Animals animals = (Animals) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(animals, System.out);
更多信息
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html【讨论】:
谢谢!我试试看! 啊,我遇到了一个小问题...我的应用程序需要支持插件,@XmlSeeAlso(Cat.class, Dog.class)
意味着我需要在编译时了解我的后代。有什么办法吗?
@fbl - 您不需要使用 XmlSeeAlso,但 JAXBContext 确实需要了解子类。您可能会发现以下方法更合适:blog.bdoughan.com/2010/08/…以上是关于JAXB 可以在基类中初始化值吗?的主要内容,如果未能解决你的问题,请参考以下文章