JAXB解组无效整数

Arn*_*was 4 cxf jaxb unmarshalling

在我们的产品中,我们使用apache CXF.由于性能限制,架构验证已设置为false.现在,对于整数元素,如果我提供的值无效,JAXB会将其解组为其他内容.例如,

9999999999转换为141006540​​7.

988888888888转换为1046410808.

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

如何处理(考虑验证将关闭)?我想要拒绝这样的价值.

bdo*_*han 7

注意: 我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JSR-222)专家组的成员.

简短的回答

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

这个相同的用例在EclipseLink JAXB(MOXy)中正常工作.


长期回答

以下是演示此问题的完整示例:

下面是带有intinteger字段的域类.

package forum13216624;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    int int1;
    int int2;
    Integer integer1;
    Integer integer2;

}
Run Code Online (Sandbox Code Playgroud)

input.xml中

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

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <int1>9999999999</int1>
    <int2>988888888888</int2>
    <integer1>9999999999</integer1>
    <integer2>988888888888</integer2>
</root>
Run Code Online (Sandbox Code Playgroud)

演示

在下面的演示代码中,我指定ValidationEventHandlerUnmarshaller.这应该捕获操作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);
    }

}
Run Code Online (Sandbox Code Playgroud)

输出 - JAXB参考实现

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

1410065407
1046410808
1410065407
1046410808
Run Code Online (Sandbox Code Playgroud)

输出 - EclipseLink JAXB(MOXy)

如果将MOXy指定为JAXB提供程序(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html ),则此用例将按预期工作.您将获得ValidationEvent每个无效值的a,如果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
Run Code Online (Sandbox Code Playgroud)

可能的解决方案

如果您的字段/属性属于类型,Integer并且您可以从JAXB参考实现切换,那么您可以创建XmlAdapter自己的 转换Integer/ String转换.

IntegerAdapter

下面是一个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);
    }

}
Run Code Online (Sandbox Code Playgroud)

包信息

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

@XmlJavaTypeAdapter(value=IntegerAdapter.class, type=Integer.class)
package forum13216624;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
Run Code Online (Sandbox Code Playgroud)

产量

以下是使用RI时的更新输出.该int值仍然是错的,但不是IntegernullValidationEvents预期生产.

java.lang.NumberFormatException: For input string: "9999999999"
java.lang.NumberFormatException: For input string: "988888888888"
1410065407
1046410808
null
null
Run Code Online (Sandbox Code Playgroud)

欲获得更多信息