如何使JAXB Marshaller根据其运行时类型编组抽象类?

栏目: Java · 发布时间: 5年前

内容简介:翻译自:https://stackoverflow.com/questions/11368076/how-to-make-jaxb-marshaller-marshal-abstract-class-based-on-its-runtime-type

考虑以下抽象类 –

public abstract class Car
{
    public abstract void drive(double miles);
}

这是扩展上述类的示例类(用于说明目的).

public class Ferrari extends Car
{
    private String lastUsed; // Ferrari specific field not in Car
    private boolean f1Car;   // Ferrari specific field not in Car

    @XmlElement
    public void setF1Car(boolean f1Car)
    {
        this.f1Car = f1Car;
    }

    public boolean isF1Car() { return f1Car; }

    @XmlElement
    public void setLastUsed(String lastUsed)
    {
        this.lastUsed = lastUsed;
    }

    public String getLastUsed() { return lastUsed; }

    public void drive(double miles)
    {
        // implementation
    }
}

我有一个包含Car对象的报表类 –

@XmlRootElement
public class CarTestReport
{
    private String date;
    private double miles;
    private Car car;

    @XmlElement
    public void setDate(String date) { this.date = date;}

    public String getDate() {return date;}

    @XmlElement
    public void setMiles(double miles) { this.miles = miles; }

    public double getMiles() {return miles;}

    @XmlElement
    public void setCar(Car car) { this.car = car; }

    public Car getCar() { return car; }
}

这里是使用JAXB来传递CarTestReport对象的代码片段 –

public static void main(String[] args) throws Exception
{
    Ferrari ferrari = new Ferrari();
    ferrari.setLastUsed("July 5 2012");
    ferrari.setF1Car(false);

    CarTestReport  report = new CarTestReport();
    report.setDate("July 6 2012");
    report.setMiles(200);
    report.setCar(ferrari);

    File file = new File("carTestReport.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(CarTestReport.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.marshal(report, file);
}

问题是,由于Car的抽象类型,JAXB忽略它并且在它对CarTestReport对象进行编组时不会对法拉利对象进行编组.我得到的输出是 –

<carTestReport>
  <car/>
  <date>July 6 2012</date>
  <miles>200.0</miles>
</carTestReport>

如您所见,即使填充了法拉利对象,也没有在“汽车”节点下输入任何内容.如何解决这个问题呢?

对于任何可能的JAXB注释类,JAXB系统都不会查看类路径.你必须帮助它找到它们.在您的示例代码中,它根本不知道法拉利类的存在. (它只能看到Car,因为这是CarTestReport中getter的返回类型.)

告诉JAXB关于法拉利的一种快速而肮脏的方法是在Car类的顶部添加@XmlSeeAlso({Ferrari.class}).然后你会得到这样的输出:

<carTestReport>
  <car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ferrari">
    <f1Car>false</f1Car>
    <lastUsed>July 5 2012</lastUsed>
  </car>
  <date>July 6 2012</date>
  <miles>200.0</miles>
</carTestReport>

告诉JAXB关于法拉利的另一种方法是将该类传递给JAXBContext.newInstance方法,即:

JAXBContext jaxbContext = JAXBContext.newInstance(CarTestReport.class,
        Ferrari.class);

或者,如果所有JAXB类都在同一个包中,例如com.mycompany.carstuff,然后你可以这样做:

JAXBContext jaxbContext = JAXBContext.newInstance("com.mycompany.carstuff");

在最后一种情况下,它将搜索该包中的所有类.

如果你想让它发出一个名为ferrari的元素(而不是像上面那样的<car xsi:type =“ferrari”>),一种可能性是将@XmlType添加到你的Car类的顶部,如下所示:

import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;

@XmlSeeAlso({Ferrari.class})
@XmlType
public abstract class Car {
  public abstract void drive(double miles);
}

…并将@XmlRootElement放在法拉利上,例如:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Ferrari extends Car {
  // ...
}

根据我的理解,这种注释组合告诉JAXB Car类映射到XML模式类型(因此你不会得到任何名为“car”的元素),并且法拉利类是该类型的元素(所以你可以有名为“ferrari”的元素. @XmlRootElement中的“根”是误导性的…它可以是对象结构中的任何元素.

翻译自:https://stackoverflow.com/questions/11368076/how-to-make-jaxb-marshaller-marshal-abstract-class-based-on-its-runtime-type


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Smashing Book

The Smashing Book

Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90

The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具