JAXB 继承,解组到编组类的子类 [英] JAXB inheritance, unmarshal to subclass of marshaled class

查看:30
本文介绍了JAXB 继承,解组到编组类的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 JAXB 来读取和写入 XML.我想要的是使用基本 JAXB 类进行编组,使用继承的 JAXB 类进行解组.这是为了允许发送方 Java 应用程序将 XML 发送到另一个接收方 Java 应用程序.发送方和接收方将共享一个公共 JAXB 库.我希望接收器将 XML 解组为特定于接收器的 JAXB 类,该 JAXB 类扩展了通用 JAXB 类.

I'm using JAXB to read and write XML. What I want is to use a base JAXB class for marshalling and an inherited JAXB class for unmarshalling. This is to allow a sender Java application to send XML to another receiver Java application. The sender and receiver will share a common JAXB library. I want the receiver to unmarshall the XML into a receiver specific JAXB class which extends the generic JAXB class.

示例:

这是发送方使用的通用 JAXB 类.

This is the common JAXB class which is used by the sender.

@XmlRootElement(name="person")
public class Person {
    public String name;
    public int age;
}

这是在解组 XML 时使用的特定于接收器的 JAXB 类.接收器类具有特定于接收器应用程序的逻辑.

This is the receiver specific JAXB class used when unmarshalling the XML. The receiver class has logic specific to the receiver application.

@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
    public doReceiverSpecificStuff() ...
}

编组按预期工作.问题在于解组,尽管 JAXBContext 使用子类 ReceiverPerson 的包名,它仍然解组到 Person.

Marshalling works as expected. The problem is with unmarshalling, it still unmarshals to Person despite the JAXBContext using the package name of the subclassed ReceiverPerson.

JAXBContext jaxbContext = JAXBContext.newInstance(package name of ReceiverPerson);

我想要的是解组到 ReceiverPerson.我能够做到这一点的唯一方法是从 Person 中删除 @XmlRootElement.不幸的是,这样做会阻止 Person 被封送.就好像 JAXB 从基类开始并向下工作,直到找到第一个具有适当名称的 @XmlRootElement.我尝试添加一个 createPerson() 方法,该方法将 ReceiverPerson 返回到 ObjectFactory 但这没有帮助.

What I want is to unmarshall to ReceiverPerson. The only way I've been able to do this is to remove @XmlRootElement from Person. Unfortunately doing this prevents Person from being marshaled. It's as if JAXB starts at the base class and works its way down until it finds the first @XmlRootElement with the appropriate name. I've tried adding a createPerson() method which returns ReceiverPerson to ObjectFactory but that doesn't help.

推荐答案

您在使用 JAXB 2.0 对吗?(JDK6 起)

You're using JAXB 2.0 right? (since JDK6)

有一个类:

javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>

哪个可以子类化,并覆盖以下方法:

which one can subclass, and override following methods:

public abstract BoundType unmarshal(ValueType v) throws Exception;
public abstract ValueType marshal(BoundType v) throws Exception;

示例:

public class YourNiceAdapter
        extends XmlAdapter<ReceiverPerson,Person>{

    @Override public Person unmarshal(ReceiverPerson v){
        return v;
    }
    @Override public ReceiverPerson marshal(Person v){
        return new ReceiverPerson(v); // you must provide such c-tor
    }
}

使用方法如下:

@Your_favorite_JAXB_Annotations_Go_Here
class SomeClass{
    @XmlJavaTypeAdapter(YourNiceAdapter.class)
    Person hello; // field to unmarshal
}

我很确定,通过使用这个概念,您可以自己控制编组/解组过程(包括选择要构造的正确 [sub|super] 类型).

I'm pretty sure, by using this concept you can control the marshalling/unmarshalling process by yourself (including the choice the correct [sub|super]type to construct).

这篇关于JAXB 继承,解组到编组类的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆