【问题标题】:XML Schema type that generates Java primitive type using JAXB doesn't add required to it使用 JAXB 生成 Java 原始类型的 XML Schema 类型不需要添加到它
【发布时间】:2012-12-10 12:55:50
【问题描述】:

我正在使用 JAXB(xjc 版本 2.2.4-2)从 XML 模式生成 Java 类。映射到 Java 原始数据类型的 XML 类型不添加:

@XmlElement(required = true)

例如使用时:

<element name="userId" type="long"/>
<element name="userName" type="string"/> 

将导致:

//no annotation added here
protected long userId;
@XmlElement(required = true)
protected String userName;

有人解释为什么会这样吗?

这是否与您可以使用 xjc 设置的选项有关?

【问题讨论】:

    标签: java jaxb xsd


    【解决方案1】:

    您不需要注释来表明需要 Java 类型 long 的属性,因为原始值不能为空这一事实是隐含的。 xs:long 类型的不可空元素映射到 Java long,可选或可空元素映射到 java.lang.Long(允许 null,表示不存在或 xsi:nil 视情况而定)。

    可选可空(奇数,但 XML Schema 允许)的元素将映射到 JAXBElement&lt;Long&gt; 以区分缺席(null JAXBElement) 和 nil(非空 JAXBElement,其 isNil() 返回 true)。

    【讨论】:

    • 我上次进行了 SOAP 测试,发现该模式具有 unsignedShort 类型的元素(因此需要隐式 minOccurs="1" -->),没有正确验证。尽管这是必需的,但我可以在请求中将其留空。
    • @JonathanRamos &lt;xs:element name="foo" type="xs:unsignedShort" /&gt; 应该映射到带有@XmlSchemaType(name = "unsignedShort")没有 @XmlElement(required = true)int 类型的属性,我刚刚在本地测试了它对我来说很好。
    • 伊恩,这就是我删除它的原因。当我再次测试时,它工作正常。所以我可能在那里做错了什么。
    • 我刚刚发现我做了什么。我已经完成了:code 这导致:​​@XmlSchemaType(name = "unsignedShort") protected Integer userNumber;
    • @JonathanRamos 是的,原理是一样的——它对可以是 null 的东西使用包装器类型,对不能使用的东西使用原始类型。
    【解决方案2】:

    如果您不介意在您的 java 类中使用 BigInteger,您可以使用 type="integer" 或 type="positiveInteger"(负 userId?)。您的验证会以这种方式进行,但需要付出一定的代价。

    另一种选择是使用 jaxb 自定义绑定。您的元素可能是:

    <element name="userId" type="long"/> 
    

    并且您必须创建一个额外的绑定文件,例如

    <jxb:bindings version="1.0" 
      xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
      jxb:extensionBindingPrefixes="xjc">
    <jxb:bindings schemaLocation="my.xsd" node="//xs:element[@name='UserType']//xs:element[@name='userId']">
     <jxb:property>
      <jxb:baseType name="java.lang.Long" />
     </jxb:property>
    </jxb:bindings>
    </jxb:bindings>
    

    现在你可以像这样调用 xjc:xjc my.xsd -b my.xjb

    这会导致:

    @XmlElement(required = true, type = Long.class) protected Integer userId;

    【讨论】:

    • 这确实会立即创建和对象 Long: @XmlElement(required = true, type = Long.class) protected Long userId;' Which doesn't let me send a request with that field being empty. Still don't understand, why adding a minOccurs=1 to for example: type="long" doesn't create a Long`。感觉像是 JAXB 的设计缺陷。
    • 同意,如果 xjc 将创建对象类型而不是基元,这将更加一致
    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2013-02-02
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多