mda*_*win 18 java xml xsd jaxb xjc
我正在将项目从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>
Run Code Online (Sandbox Code Playgroud)
生成的类看起来像这样:
public class UsageAuthRateCharge {
........
public Boolean isPricepointCustomFieldsRequired() {
return pricepointCustomFieldsRequired;
}
Run Code Online (Sandbox Code Playgroud)
问题是虽然装箱会起作用,但如果提供的XML不包含值pricepoint_custom_fields_required,则类的布尔字段为空,而不是false.这样做的时候我得到NullPointerExceptions:
methodWhichTakesPrimitiveBooleanArg(myUsageAuthRateChargeInstance.isPricepointCustomFieldsRequired());
Run Code Online (Sandbox Code Playgroud)
因为它试图取消传入的布尔值 - 除了它为空.
我无法更改架构,我无法调整所有客户端代码来进行空检查.
我在binding.xml中设置了optionalProperty属性,如下所示:
<globalBindings optionalProperty="primitive">
Run Code Online (Sandbox Code Playgroud)
在规范中,它说:"如果属性的值是"原始的",它会像在JAXB 1.0中那样绑定"
然而,这显然没有发生.
我怎么解决这个问题?
更新:
这现在在jaxb 2.2.9中修复:https://java.net/jira/browse/JAXB/fixforversion/16850
bdo*_*han 27
你所得到的原因Boolean,而不是boolean是,你必须minOccurs="0"在你的元素定义.甲null值将被存储为不存在的元素.
<xs:element name="pricepoint_custom_fields_required" type="xs:boolean" minOccurs="0"/>
Run Code Online (Sandbox Code Playgroud)
解决方案应该是一个外部绑定文件,指示应该将基本类型用于可选值(请参阅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>
Run Code Online (Sandbox Code Playgroud)
使用-bXJC选项指定外部绑定文件.
xjc -b binding.xml my-schema.xsd
Run Code Online (Sandbox Code Playgroud)
已打开以下错误以跟踪问题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>
Run Code Online (Sandbox Code Playgroud)
UsageAuthRateCharge
使用您想要的方法创建此类.
XJC电话
使用-bXJC调用上的标志指定binding.xml文件
xjc -b binding.xml my-schema.xsd
Run Code Online (Sandbox Code Playgroud)
我真正希望的是,其中一位读者可能是一名jaxb开发团队成员,可以轻松地在jaxb中进行更改.用户archenroot在他对jaxb issue 927(926的重复)的评论中提供了一个可能的解决方案,这使我认为对于合适的人来说,修复jaxb将是一项简单的工作
我是EclipseLink JAXB(MOXy)的领导者.我已经联系了执行JAXB参考实现的同事(他们也适用于Oracle).以下是我从他们那里得到的答复:
我已经在后备箱测试了 - 问题就存在了.我会检查代码修复它有多容易.
希望你能够真正解决这个问题.
我厌倦了等待开发团队的修复,所以我卷起袖子自己做了。
我添加了下面的代码来帮助那些也有此问题的人。
免责声明:我的代码可能不是解决问题的最佳方法,但它对我有用。
生成的代码现在如下所示:
public boolean isPricepointCustomFieldsRequired() {
if (pricepointCustomFieldsRequired == null) {
return false;
} else {
return pricepointCustomFieldsRequired;
}
}
Run Code Online (Sandbox Code Playgroud)
并且修改如下:
com.sun.tools.xjc.reader.xmlschema.bindinfo.BIProperty:createElementProperty,第 358 行
行后
类型.addTo(prop);
插入以下代码:
if (prop.isOptionalPrimitive() && getOptionalPropertyMode() == OptionalPropertyMode.PRIMITIVE &&
!prop.getTypes().isEmpty() && "boolean".equals(prop.getTypes().get(0).getTypeName().getLocalPart()) ) {
prop.defaultValue= CDefaultValue.create(CBuiltinLeafInfo.BOOLEAN, new XmlString("false"));
}
Run Code Online (Sandbox Code Playgroud)