JAXB拆除无效整数



在我们的产品中,我们使用apache cxf。由于性能限制,架构验证已设置为错误。现在,对于一个整数元素,如果我提供无效的值,Jaxb将其删除其他东西。例如,

9999999999被转换为1410065407。

988888888888转换为1046410808。

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

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

注意:我是 eclipselink Jaxb(moxy) lead和Jaxb(JSR-222)专家组的成员。

简短答案

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

  • http://java.net/jira/browse/jaxb/

在Eclipselink Jaxb(Moxy)中,同一用例正常工作。


长答案

以下是一个完整的示例,证明了问题:

root

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

package forum13216624;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
    int int1;
    int int2;
    Integer integer1;
    Integer integer2;
}

input.xml

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

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <int1>9999999999</int1>
    <int2>988888888888</int2>
    <integer1>9999999999</integer1>
    <integer2>988888888888</integer2>
</root>

demo

在下面的演示代码中,我在Unmarshaller上指定了ValidationEventHandler。对于unmarhsal操作中遇到的任何无效值,这都应捕获ValidationEvent

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-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 to/from 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);
    }
}

package-info

在软件包级别使用@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

有关更多信息

  • http://blog.bdoughan.com/2011/05/jaxb-and-joda time-dates-and-dates-and-times.html

最新更新