无效整数的JAXB解组

无效整数的JAXB解组,jaxb,cxf,unmarshalling,Jaxb,Cxf,Unmarshalling,在我们的产品中,我们使用apache CXF。由于性能限制,架构验证已设置为false。现在,对于一个整数元素,如果我提供了一个无效的值,JAXB会将其解组到其他对象。比如说, 9999999999转换为1410065407 988888888转换为1046410808 我的问题是这里遵循的逻辑(公式)是什么 如何处理(考虑到验证将关闭)?我希望这样的值被拒绝。注意:我是专家组的负责人和成员 简短回答 这似乎是JAXB参考实现中的一个bug。我建议在以下位置输入错误: 同样的用例在Ecli

在我们的产品中,我们使用apache CXF。由于性能限制,架构验证已设置为false。现在,对于一个整数元素,如果我提供了一个无效的值,JAXB会将其解组到其他对象。比如说,

9999999999转换为1410065407

988888888转换为1046410808

我的问题是这里遵循的逻辑(公式)是什么


如何处理(考虑到验证将关闭)?我希望这样的值被拒绝。

注意:我是专家组的负责人和成员

简短回答

这似乎是JAXB参考实现中的一个bug。我建议在以下位置输入错误:

同样的用例在EclipseLink JAXB(MOXy)中也能正常工作


长答案

下面是一个完整的示例,演示了该问题:

根目录

下面是一个具有
int
integer
字段的域类

UM13216624的
包;
导入javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
公共类根{
int int1;
int int2;
整数1;
整数2;
}
input.xml

下面是一个XML文档,其中包含您的问题中的值


9999999999
988888888888
9999999999
988888888888
演示

在下面的演示代码中,我在
解组器上指定了一个
ValidationEventHandler
。这将捕获
ValidationEvent
,以查找
unmarshal
操作期间遇到的任何无效值

UM13216624的
包;
导入java.io.File;
导入javax.xml.bind.*;
公开课演示{
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(Root.class);
Unmarshaller Unmarshaller=jc.createUnmarshaller();
unmarshaller.setEventHandler(新的ValidationEventHandler(){
@凌驾
公共布尔handleEvent(ValidationEvent事件){
System.out.println(event.getMessage());
返回true;
}}
);
文件xml=新文件(“src/forum13216624/input.xml”);
Root=(Root)unmarshaller.unmarshal(xml);
System.out.println(root.int1);
System.out.println(root.int2);
System.out.println(root.integer1);
System.out.println(root.integer2);
}
}
输出-JAXB参考实现

此输出与您看到的行为相匹配

1410065407
1046410808
1410065407
1046410808
输出-EclipseLink JAXB(MOXy)

如果您指定MOXy作为您的JAXB提供程序(请参阅:),则此用例将按预期工作。对于每个无效值,您将获得一个
ValidationEvent
,如果处理了
ValidationEvent
,则字段/属性不会设置为无效值

Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int1-->int1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "9999999999"

Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int2-->int2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "988888888888"

Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer1-->integer1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "9999999999"

Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer2-->integer2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "988888888888"
0
0
null
null

潜在解决方案

如果字段/属性的类型为
Integer
,并且可以从JAXB参考实现中切换,则可以创建
XmlAdapter
来执行自己的
Integer
String
的转换

整数适配器

下面是一个
XmlAdapter
示例,演示如何提供自己的转换逻辑

UM13216624的
包;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
公共类IntegerAdapter扩展了XmlAdapter{
@凌驾
公共整数解组(字符串)引发异常{
返回整数.valueOf(字符串);
}
@凌驾
公共字符串封送处理(整数)引发异常{
返回字符串.valueOf(整数);
}
}
套餐信息

在包级别使用
@XmlJavaTypeAdapter
注释意味着
XmlAdapter
将应用于此包中类的
Integer
类型的所有字段/属性

@XmlJavaTypeAdapter(value=IntegerAdapter.class,type=Integer.class)
13216624包;
导入javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
输出

以下是使用RI时更新的输出。
int
值仍然错误,但不是
Integer
值为
null
并且
ValidationEvents
按预期生成

java.lang.NumberFormatException: For input string: "9999999999"
java.lang.NumberFormatException: For input string: "988888888888"
1410065407
1046410808
null
null
了解更多信息


非常感谢您澄清这个问题!对于我们的产品,切换JAXB引用实现可能是不可能的,但是将integer类型的元素声明为string可能是一个潜在的解决方案。@ArnabBiswas-您不需要将元素设置为
string
。相反,我建议通过
XmlAdapter
提供您自己的
字符串
/
整数
转换逻辑。我已经用一个完整的例子更新了我的答案。再次感谢。很抱歉,我的评论不够清晰。但是,这也是我正在考虑的。布莱斯·道格汉——你是对的。我对适配器的概念不正确。