我正在将一个项目从JAXB 1.0迁移到JAXB 2.1,但在数据类型映射方面遇到了问题。
我使用的是Ant xjc绑定编译器,并且我已经成功地配置了全局绑定,使(例如) xs:date映射到java.util.Calendar。
然而,我得到的是返回Boolean
的生成方法,而我想要的是boolean
。
下面是复杂类型:
<xs:element name="usage-auth-rate-charge">
<xs:complexType>
<xs:sequence>
<xs:element name="service-id" type="xs:string"/>
<xs:element name="pricepoint_custom_fields_required" type="xs:boolean" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
生成的类如下所示:
public class UsageAuthRateCharge {
........
public Boolean isPricepointCustomFieldsRequired() {
return pricepointCustomFieldsRequired;
}
问题是,尽管装箱可以正常工作,但是如果提供的XML不包含pricepoint_custom_fields_required
的值,那么该类的布尔值字段就是空的,而不是假的。所以我在做这样的事情时会得到NullPointerExceptions:
methodWhichTakesPrimitiveBooleanArg(myUsageAuthRateChargeInstance.isPricepointCustomFieldsRequired());
因为它试图对传入的布尔值进行拆箱-除非布尔值为空。
我不能更改模式,也不能调整所有客户端代码来执行null检查。
我在binding.xml中设置了optionalProperty属性,如下所示:
<globalBindings optionalProperty="primitive">
在规范中,它说:“如果属性值是"primitive",它就像在JAXB1.0中那样绑定。”
然而,这显然没有发生。
我该如何解决这个问题?
更新:
这个问题现在已经在jaxb 2.2.9:https://java.net/jira/browse/JAXB/fixforversion/16850中修复了
发布于 2013-12-13 23:21:05
问题
获取Boolean
而不是boolean
的原因是您的元素定义中包含了minOccurs="0"
。将为缺少的元素存储null
值。
<xs:element name="pricepoint_custom_fields_required" type="xs:boolean" minOccurs="0"/>
解决方案应该是什么
解决方案应该是一个外部绑定文件,该文件指示应该对可选值使用原语类型(请参阅JAXB 2.2规范的7.5.1节)。
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:globalBindings optionalProperty="primitive"/>
</jaxb:bindings>
外部绑定文件是使用XJC的-b
选项指定的。
xjc -b binding.xml my-schema.xsd
为什么该解决方案不起作用
已打开以下错误来跟踪optionalProperty="primitive"
的问题。
解决方法
如果您不喜欢在JAXB中生成类的方式,那么可以自己创建一个类,并让JAXB将其作为模式的一部分引入到类生成中。
binding.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:bindings schemaLocation="my-schema.xsd">
<jxb:bindings node="//xs:element[@name='usage-auth-rate-charge']/complexType">
<jxb:class ref="com.example.foo.UsageAuthRateCharge"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
UsageAuthRateCharge
用你想要的方法创建这个类。
XJC调用
在XJC调用中使用-b
标志来指定binding.xml
文件
xjc -b binding.xml my-schema.xsd
更新
我真正希望的是,读者中可能有一位是jaxb开发团队的成员,他可以用jaxb轻松地完成更改。用户archenroot在他对jaxb问题927 (926的副本)的评论中提供了一个可能的解决方案,这使我认为对于合适的人来说,修复jaxb将是一项简单的工作。
我是的领导。我已经联系了负责JAXB参考实现的同事(他们也为Oracle工作)。以下是我从他们那里得到的回复:
我在主干中测试过
--问题确实存在。我将检查代码修复它有多容易。
希望你能得到这个问题的真正解决方案。
发布于 2012-10-26 06:02:53
试试这个。
<xs:element name="usage-auth-rate-charge">
<xs:complexType>
<xs:sequence>
<xs:element name="service-id" type="xs:string"/>
</xs:sequence>
<xs:attribute name="chosen" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
我发现了你的问题,因为我正在寻找如何做你正在做的完全相反的事情。我有一个布尔属性,它只会生成将该属性作为原始布尔值的代码。为了让jaxb将这个属性作为布尔对象而不是布尔原语生成,我在xsd中删除了属性定义中的use=“use=”部分。
发布于 2018-09-24 16:14:10
只是为了让它完整
type="xs:boolean" minOccurs="0" maxOccurs="1" == Boolean value (object)
type="xs:boolean" minOccurs="0" maxOccurs="1" nillable="true" == JAXBElement<Boolean> value (object)
type="xs:boolean" minOccurs="1" maxOccurs="1" == boolean value (primitive)
type="xs:boolean" minOccurs="1" maxOccurs="1" nillable="true" == Boolean value (object)
https://stackoverflow.com/questions/13035975
复制相似问题