如何使用XmlAdapter将XML复杂类型映射到模式生成的类中的Java对象?

时间:2016-08-25 09:02:55

标签: java xml jaxb xjc

使用这个(演示)模式,我使用JAXB生成Java对象:

<xsd:complexType name="someType">
    <xsd:sequence>
        <xsd:element name="myOtherType" type="otherType" maxOccurs="unbounded" />
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="otherType">
    <!-- ... -->
</xsd:complexType>

生成此类:

@XmlType
public class SomeType {

    @XmlElement(name = "myOtherType")
    OtherType myOtherType;

}

但是我想在我的JAXB生成的对象中使用接口而不是实现。

所以我写这个界面:

public interface OtherTypeInterface {
    // ....
}

我让生成的OtherType类在绑定文件的帮助下实现它:

<jxb:bindings node="//xs:complexType[@name='otherType']">
    <inheritance:implements>com.example.OtherTypeInterface</inheritance:implements>
</jxb:bindings> 

到目前为止,非常好:

public class OtherType implements OtherTypeInterface {

    // ...

}

但是我也需要SomeType对象来使用这个接口,而不是OtherType实现。正如 3.2.2部分中建议的in the unofficial JAXB guide。使用@XmlJavaTypeAdapter ,我想使用自制的XML适配器将OtherType映射到其界面,反之亦然:

public class HcpartyTypeAdapter extends XmlAdapter<OtherType, OtherTypeInterface> {

    @Override
    public OtherTypeInterface unmarshal(OtherType v) throws Exception {
        return v;
    }

    @Override
    public OtherType marshal(OtherTypeInterface v) throws Exception {
        return (OtherType) v;
    }

}

但是看起来在我的绑定文件中使用以下配置映射XML复杂类型是一个很大的禁忌:

<jxb:globalBindings>
    <xjc:javaType name="com.example.OtherTypeInterface" xmlType="ex:otherType" adapter="com.example.OtherTypeAdapter"/>
</jxb:globalBindings>

生成因此错误而失败:

  

com.sun.istack.SAXParseException2; systemId:file:/.../ bindings.xjb;   lineNumber:8; columnNumber:22;未定义的简单类型   “{http://www.example.com} OTHERTYPE”。

使用a bit of googling,我发现在模式生成的类中使用XML适配器显然不可能用于复杂类型。但是,如果我手动编辑文件以使用我的适配器,它可以完美地运行:

public class SomeType {

    @XmlElement(name = "myOtherType")
    @XmlJavaTypeAdapter(OtherTypeAdapter.class)
    @XmlSchemaType(name = "otherType")   
    OtherTypeInterface myOtherType;

}

我可以完美地整理和解组它;但在我看来,编辑生成的类会破坏自动处理的整个目的。我正在处理定义许多类型的多个模式。

所以我的问题是:有没有人知道使用XML适配器将XML复杂类型映射到模式生成的类中的Java对象而不需要手动编辑代码的解决方法?

可能的答案在这里:https://stackoverflow.com/a/1889584/946800。我希望自2009年以来,有人可能找到了解决这个问题的方法......

1 个答案:

答案 0 :(得分:0)

您可以使用jaxb2 annotate maven插件为生成的JAXB类添加注释。

            <plugin>
                <!-- this plugin is used to add annotation for the models -->
                <groupId>org.jvnet.jaxb2_commons</groupId>
                <artifactId>jaxb2-basics-annotate</artifactId>
                <version>1.0.2</version>
            </plugin>

.xjb绑定中,

<jxb:bindings schemaLocation="sample.xsd">
    <jxb:bindings node="//xs:complexType[@name='otherType']">
        <annox:annotate target="field">
            <annox:annotate annox:class="@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter"
                value="com.example.OtherTypeAdapter.class" />
        </annox:annotate>
    </jxb:bindings>
</jxb:bindings>