将xs:integer绑定到Java Integer而不是BigInteger的JAXB绑定

7
以下讨论应避免。这个问题不是:
- 使用xs:int而不是xs:integer。 - 使用primitive int而不是Integer。 - 为什么你需要这个。 - 如果等等,你会做什么。
问题:
我想要一个jaxb绑定声明的示例,以覆盖将xs:integer默认映射到Java BigInteger,使得xjc会生成Java Integer。
例如:
<xs:attribute name="id" type="xs:integer"/>

应该产生
@XmlAttribute(name = "id")
Integer id;

并且不是

@XmlAttribute(name = "id")
BigInteger id;

如果相应的文档元素包含一个值≥ 2³¹,您期望JAXB执行什么操作? - VGR
毫不担心。 - Blessed Geek
这个问题没有答案吗?我在谷歌上找到了。 - Claude Martin
4个回答

7
你可以将以下内容添加到你的绑定文件中:
<globalBindings>
    <javaType xmlType="xs:integer" name="java.lang.Integer"/> 
</globalBindings>

这将例如产生以下结果:
@XmlAttribute(name = "id")
@XmlJavaTypeAdapter(Adapter1 .class)
protected Integer id;

public int getId() {
    if (id == null) {
        return new Adapter1().unmarshal("0");
    } else {
        return id;
    }
}

public void setId(Integer value) {
    this.id = value;
}

3
@JeroenVanMontfort的回答是可行的方法,但是由于缺少命名空间声明和设置细节,它不能直接使用。因此,如果您需要更多关于此的详细信息,请参考以下内容。
创建绑定文件有多种方法,但是您也可以创建嵌入式绑定,但是为了这个问题的缘故,我将跳过该部分。但是,如果您想详细了解绑定文件还可以实现什么,请查看coderleaf的博客
以下是一个简单的绑定文件示例,创建全局绑定以确保xs:integer被转换为java.lan.Integer而不是BigInteger,并且它还定义了将枚举值绑定为整数的特定绑定(尽管这不是问题的一部分,但是添加它只是为了说明混合绑定)。
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://java.sun.com/xml/ns/jaxb https://java.sun.com/xml/ns/jaxb/bindingschema_2_1.xsd"
    version="2.1">
        <jxb:globalBindings>
            <jxb:javaType xmlType="xs:integer" name="java.lang.Integer" />
        </jxb:globalBindings>
        <jxb:bindings schemaLocation="../xsd/myService.xsd">
            <jxb:bindings node="//xs:simpleType[@name='DayOfWeek']/xs:restriction/xs:enumeration[@value='1']">
                <jxb:typesafeEnumMember name="Monday" />
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='DayOfWeek']/xs:restriction/xs:enumeration[@value='2']">
                <jxb:typesafeEnumMember name="Tuesday" />
            </jxb:bindings>
        </jxb:bindings>
    </jxb:bindings>

以下是一个xsd的示例(我刚刚手工制作的,可能含有错误,请注意)。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://my.service.com/model"
    targetNamespace="http://my.service.com/model" elementFormDefault="qualified">

    <xs:element name="MyElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="field1" type="xs:integer"/>
                <xs:element name="field2" type="tns:DayOfWeek"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="DayOfWeek">
        <xs:restriction base="xs:string">
            <xs:enumeration value="1" />
            <xs:enumeration value="2" />
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

以上将创建类似于以下的类(我没有包括toString,hash,equals和其他函数以保持简洁):
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MyElement", propOrder = {
    "field1",
    "field2"
})
public class MyElement implements Equals2, HashCode2, ToString2
{
    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "integer")
    protected Integer field1;
    
    @XmlElement(name = "DayOfWeek", required = true)
    @XmlSchemaType(name = "string")
    protected DayOfWeek field2;

    public Integer getField1() {
        return field1;
    }
    public DayOfWeek getField2() {
        return field2;
    }    
}

还要注意枚举

@XmlType(name = "DayOfWeek")
@XmlEnum
public enum DayOfWeek {

    @XmlEnumValue("1")
    Monday("1"),
    @XmlEnumValue("2")
    Tuesday("2");
    private final String value;

    DayOfWeek(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static DayOfWeek fromValue(String v) {
        for (DayOfWeek c: DayOfWeek.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }
}

2

全局覆盖可以在绑定文件中使用以下内容:

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"
          xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <globalBindings>
        <javaType xmlType="xs:integer" name="java.lang.Integer"/> 
    </globalBindings>
</bindings>

要覆盖特定类型的用法,请使用以下内容:

使用以下内容:

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1"
          xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <bindings schemaLocation="../xsd/foo.xsd">
        <bindings node="//xs:complexType[@name='bar']/xs:attribute[@name='id']">
            <property>
                <baseType>
                    <javaType name="java.lang.Integer"/>
                </baseType>
            </property>
        </bindings>
    </bindings>
</bindings>

通过使用schemaLocationnode属性中的XPath表达式,您可以根据需要限制覆盖。"Original Answer"翻译成"最初的回答"。

2

关于属性:

<xs:attribute name="id" type="xs:int" />

对于元素:

<xs:element name="id" type="xs:int" minOccurs="0" />

这应该是被接受的答案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接