在我们的产品中,我们使用 apache CXF。由于性能限制,模式验证已设置为 false。现在,对于一个整数元素,如果我提供了一个无效值,JAXB 会将它解组为其他东西。例如,
9999999999 转换为 1410065407。
988888888888 转换为 1046410808。
我的问题是这里遵循的逻辑(公式)是什么?
如何处理这个(考虑到验证将被关闭)?我希望这样的值被拒绝。
在我们的产品中,我们使用 apache CXF。由于性能限制,模式验证已设置为 false。现在,对于一个整数元素,如果我提供了一个无效值,JAXB 会将它解组为其他东西。例如,
9999999999 转换为 1410065407。
988888888888 转换为 1046410808。
我的问题是这里遵循的逻辑(公式)是什么?
如何处理这个(考虑到验证将被关闭)?我希望这样的值被拒绝。
注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。
简短的回答
这似乎是 JAXB 参考实现中的一个错误。我建议在以下位置为其输入错误:
同样的用例在 EclipseLink JAXB (MOXy) 中也能正常工作。
长答案
以下是演示该问题的完整示例:
根
下面是一个带有int
和integer
字段的域类。
package forum13216624;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
int int1;
int int2;
Integer integer1;
Integer integer2;
}
输入.xml
下面是一个 XML 文档,其中包含您问题中的值。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<int1>9999999999</int1>
<int2>988888888888</int2>
<integer1>9999999999</integer1>
<integer2>988888888888</integer2>
</root>
演示
在下面的演示代码中,我ValidationEventHandler
在Unmarshaller
. 这应该捕获操作ValidationEvent
期间遇到的任何无效值unmarhsal
。
package forum13216624;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
@Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getMessage());
return true;
}}
);
File xml = new File("src/forum13216624/input.xml");
Root 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 提供程序(请参阅:http ://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html ),此用例将按预期工作。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
演示如何提供自己的转换逻辑的示例。
package forum13216624;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class IntegerAdapter extends XmlAdapter<String, Integer>{
@Override
public Integer unmarshal(String string) throws Exception {
return Integer.valueOf(string);
}
@Override
public String marshal(Integer integer) throws Exception {
return String.valueOf(integer);
}
}
包信息
在包级别使用@XmlJavaTypeAdapter
注释意味着XmlAdapter
将应用于Integer
此包中类的所有类型的字段/属性。
@XmlJavaTypeAdapter(value=IntegerAdapter.class, type=Integer.class)
package forum13216624;
import 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
了解更多信息