【问题标题】:Custom serialization in JAXBJAXB 中的自定义序列化
【发布时间】:2010-10-05 11:15:27
【问题描述】:

有没有办法在 JAXB 中自定义 XML 序列化,就像在 .NET 中使用 IXmlSerializable 一样? (即使用等效的 XmlReader/Writer 直接控制对象序列化的能力)。

我查看了 XmlAdapter 和 @XmlJavaTypeAdapter,但它们似乎只是用于将类型转换为可序列化表单和从可序列化表单转换,这并不是我想要的。

更新:特别是,我想自定义根对象的反序列化,它以编程方式确定如何反序列化内部 XML(例如,创建具有一组特定已知类型的 jaxb 解组器)。

更新:我找到了解决问题的方法,但这是一个令人讨厌的 hack,我可能会采用其他海报建议的解决方案之一。

【问题讨论】:

  • 您能否提供更多关于您希望如何自定义序列化的信息?例如,您不希望 XML 标记名称与字段名称相同。

标签: java xml xml-serialization jaxb


【解决方案1】:

好的,所以我设法让这个工作,虽然这是一个非常讨厌的解决方案,我想我会找到解决问题的更高级别的方法,正如 Fabian 和 basszero 所提到的。以下代码的想法是创建一个对您要序列化的数据的通用可序列化引用,它维护一个 JAXB java 类型适配器以以编程方式执行序列化,以及一个存储生成的 XML 的字符串字段。

注意:代码已大大简化以进行显示...

// Create an instance of this class, to wrap up whatever you want to custom-serialize
@XmlRootElement
public static class SRef
{
    public SRef() { }
    public SRef(Object ref)
    {
        this.ref = ref;
    }

    @XmlJavaTypeAdapter(SRefAdapter.class)
    public Object ref;
}

// This is the adapted class that is actually serialized 
public static class SRefData
{
    // This is a hint field to inform the adapter how to deserialize the xmlData
    @XmlAttribute
    public String hint;

    // This contains the custom-serialized object
    @XmlElement
    public String xmlData;
}

    // Converts an object to and from XML using a custom serialization routine
public static class SRefAdapter extends XmlAdapter<SRefData, Object>
{
    @Override
    public SRefData marshal(Object value) throws Exception
    {
        if (value instanceof MyType)
        {
            SRefData data = new SRefData();
            data.xmlData = doSomeSpecificSerialization(value);
            data.hint = "myType";
            return data;
        }
        throw new IllegalArgumentException("Can't serialize unknown object type " + value.getClass());
    }

    @Override
    public Object unmarshal(SRefData refData) throws Exception
    {
        if (refData.hint.equals("myType"))
        {
            return doSomeSpecificDeserialization(refData.xmlData);
        }
        throw new IllegalArgumentException("Unhandled hint value in SRefData: " + refData.hint); 
    }
}

【讨论】:

    【解决方案2】:

    我不确定我完全理解你的目标是什么,但也许你可以在你的根对象的无参数构造函数中以编程方式做你想做的事情,当它被解组时将被调用来实例化对象.

    【讨论】:

      【解决方案3】:

      听起来您希望根节点包含两组不同的 xml 节点/树,这基于从根节点本身获得的某种属性或知识。

      我倾向于通过首先创建一个模式 (xsd) 然后生成 Java 源代码来使用 JAXB,我从不修改它。我只修改架构和再生。我意识到JAXB不能以其他方式使用,通过注释源,购买我不能那样说,因为我不使用它。如果您是架构...请继续阅读

      考虑一下:http://www.w3schools.com/Schema/schema_complex_indicators.asp

      不要切换解组器,只需包含两个 xml 定义。无论如何,它们都会被解析,您可以通过在根节点上检查的任何属性来改变程序控制流。

      【讨论】:

      • 你解决了我的问题 - 正确。绝对同意 XSD,但我还没有将其标记为已接受,因为我认为可能有一种方法可以通过使用 XmlAdapters 来解决我的问题。我们会看到...
      猜你喜欢
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多