【问题标题】:Customize object/element name with JAXB使用 JAXB 自定义对象/元素名称
【发布时间】:2018-09-29 13:33:16
【问题描述】:

我对 JAXB 很陌生,所以在破解这个(我认为)非常简单的用例时遇到了麻烦。

我有一组模式。我无法控制这些,我无法改变它们。在这些模式中,我有诸如

之类的声明
<xs:complexType name="CustomerType">
    ...

我尝试从这些生成类。所以这样的声明就变成了

@XmlType(name = "CustomerType", propOrder = {
    "field1",
    "field2"
})
public class CustomerType {
    ...

然后我需要使用这个类来使用 RestTemplate 创建 XML 消息。问题是,XML 消息中的对象不应该是“CustomerType”,而应该只是“Customer”。就像我说的,我不能编辑模式。我也不能直接编辑生成的源。我需要某种外部定制来告诉源生成过程或编组过程如何转换对象的名称。任何建议将不胜感激。

【问题讨论】:

    标签: java jaxb resttemplate jaxb2 jackson2


    【解决方案1】:

    您可以使用绑定来自定义类或属性名称。通常你会有一个像 bindings.xjb 这样的文件:

    <jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        jaxb:extensionBindingPrefixes="xjc">
    
        <jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
            <jaxb:bindings node="xsd:customType[@name='CustomerType']">
                <jaxb:class name="Customer"/>
            </jaxb:bindings>
            <jaxb:bindings node="xsd:customType[@name='CustomerType']//xsd:element[@name='field1']">
                <jaxb:property name="f1"/>
            </jaxb:bindings>
        </jaxb:bindings>
    </jaxb:bindings>
    

    您可以使用绑定自定义很多东西(请参阅this),但肯定不是全部。

    【讨论】:

    • 谢谢。我看不到使用外部绑定文件自定义根对象名称的方法(不仅是类,还有将用于编组的名称,在 @XmlType 注释中的名称属性)。
    • 您确定必须为此更改@XmlType 吗?这是可行的,但我怀疑杰克逊真的接受@XmlType
    • 我措辞不正确。我的意思是我需要更改@XmlType 定义的值。我实际上无法更改注释本身,因为它位于生成的源中。这就是为什么我正在寻找一种方法来以某种方式使用外部文件。
    • @Sethiel 好吧,你可能措辞不正确,但现在它的措辞就像它的措辞一样,这就是答案。
    • @Sethiel 我可以向您展示如何使用jaxb2-annotate-plugin 修改@XmlType,但首先让我们完成这个问题。接受答案,再问一个问题。
    【解决方案2】:

    DTO对象的创建方式是:

    您在一处定义所有类型,例如:CustomerType、UserType、OrderType 等。

    然后您创建另一个架构并在您定义了多种类型的地方导入适当的 XSD。然后,您实际使用/聚合这些类型定义来为对象创建 XML 模式。类似下面的东西

    <xs:complexType name="CustomerOrders">
    <xs:element name="Customer" type="CustomerType">
    <xs:attribute name="Orders" type="OrderType">
    

    【讨论】:

    • 我不明白你的建议。另外,对于每个服务,我只有一个用于请求的 xsd 文件和一个用于响应的文件。
    • 您必须有另一个包装 CustomerType 对象的 Wrapper ComplexType。正如您所提到的,您的 Request 和 Response 对象各有一个 XSD,那么您的 Request 对象必须有一个 xs:element,其类型为 CustomerType。您可以分享您的 Request XSD 吗?
    • 我认为我不能共享 XSD。但是,是的,我确实有另一个包装器 complexType。 &lt;xs:complexType name="individualType"&gt; &lt;xs:sequence&gt; &lt;xs:element name="individual-name" type="individual-nameType"/&gt; &lt;xs:element name="date-of-birth" type="xs:string"/&gt; &lt;/xs:sequence&gt; &lt;/xs:complexType&gt; 之类的东西在同一个文件中,我无法编辑。现在我需要将这些对象翻译为“个人”和“个人名称”。你到底建议我做什么?
    • 从这里可以看出,personal-name、date-of-birth 是 individualType 对象的子对象,因此可以通过获取 individualType 对象的实例来使用。您需要搜索 XSD 以查找是否有任何包含单个类型的 complexType。
    • 好吧,原来我很无知,我问错了问题。那么,让我从头开始问:如何在不更改架构或向生成的代码添加任何注释的情况下更改 root complexType 将被编组的名称?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多