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 可以在基类中初始化值吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在基类初始化程序中调用默认构造函数?

是否可以通过在基类中添加新的虚函数来破坏代码?

使用初始化列表时如何获取私有数据?

在基类中存储指向派生类函数的指针

在基类中访问 QPainter

如何在构造函数中注入 IEnumerable<ICustomRepository>,以便我可以决定在基类中使用哪一个?