java - 具有多级继承的 XmlDiscriminatorNode/XmlDiscriminatorValue

标签 java jax-rs moxy

我有以下域模型:

@XmlDiscriminatorNode("@type")
class Vehicle

@XmlDiscriminatorValue("car")
class Car extends Vehicle

@XmlDiscriminatorValue("tank")
class Tank extends Vehicle

@XmlDiscriminatorValue("sedan")
class Sedan extends Car

在我的顶级模型类中,我有一个 List<Vehicle>我想序列化。我想用 moxy 序列化这个模型,以便 Sedan 中的字段显示出来。当我添加XmlDiscriminatorNode时到车辆并添加 XmlDiscriminatorValue对于扩展类,仅序列化第一级继承。在上面的示例中,显示了 Car 的属性,但没有显示 Sedan 的属性。如何注释这些类以便显示 Sedan 的属性?

最佳答案

当 JAXB 派生模型传递关系的元数据时,将进行处理。当处理一个类时,它的父类(super class)也会被处理,但不会处理它的子类。为了克服这个问题,您需要让 JAXB 了解子类。实现此目的的一种方法是使用 @XmlSeeAlso 注释。

<小时/>

Java 模型

我将使用您问题中的 Java 模型并进行以下更改:

车辆

我添加了 @XmlSeeAlso 注释。只需添加叶类,因为处理 Sedan 将导致处理 Car 类。

import javax.xml.bind.annotation.XmlSeeAlso;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;

@XmlDiscriminatorNode("@type")
@XmlSeeAlso({Tank.class, Sedan.class})
class Vehicle {}

轿车

我已向 Sedan 类添加了一个属性,以表明它出现在编码结果中。

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;

@XmlDiscriminatorValue("sedan")
class Sedan extends Car {

    private String sedanProperty;

    public String getSedanProperty() {
        return sedanProperty;
    }

    public void setSedanProperty(String sedanProperty) {
        this.sedanProperty = sedanProperty;
    }

}

这是一个根类,正如您在问题中所描述的那样,它具有 Vehicle 对象的 List

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Foo {

    private List<Vehicle> vehicles = new ArrayList<Vehicle>();

    @XmlElement(name="vehicle")
    public List<Vehicle> getVehicles() {
        return vehicles;
    }


}

演示代码

演示

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Sedan sedan = new Sedan();
        sedan.setSedanProperty("Sedan Value");

        Foo foo = new Foo();
        foo.getVehicles().add(sedan);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(foo, System.out);
    }

}

输出

<?xml version="1.0" encoding="UTF-8"?>
<foo>
   <vehicle type="sedan">
      <sedanProperty>Sedan Value</sedanProperty>
   </vehicle>
</foo>

关于java - 具有多级继承的 XmlDiscriminatorNode/XmlDiscriminatorValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21030643/

相关文章:

java - 在 Android 上使用 REST 服务,最简单的方法?

java - Jersey @DefaultValue 不适用于正则表达式定义的路径

java - 如何在没有工作区和其他 Eclipse 默认功能的情况下创建 RCP 项目?

java - 将 Jparepository 的 FindAll 方法与 ModelAndView 结合使用

java - 配置 Jersey MVC 以在没有 web.xml 的情况下提供 Viewable

java - 如何配置 JAXB/Moxy 以针对 XML 中可能丢失的数据抛出错误

java - 只有一个 XMLElementRef 编码

java - JAXB 映射 将复杂对象映射到 JSON

java - MultiActionController 的替换类,在 4.3.3 中已弃用

java - 如何解决 bootcamp-cordapp 中的 NotSerializedException。测试合约时