在我們的產品中我們使用apache CXF。由於性能限制,模式驗證已設置爲false。現在,如果我提供了一個無效值,那麼對於一個整數元素,JAXB將它解組到另外一些東西。例如,JAXB解組無效整數
9999999999變換成1410065407.
988888888888被轉換成1046410808.
我的問題是什麼是正在這裏遵循的邏輯(公式)?
如何處理(考慮驗證將關閉)?我想要這樣的價值被拒絕。
在我們的產品中我們使用apache CXF。由於性能限制,模式驗證已設置爲false。現在,如果我提供了一個無效值,那麼對於一個整數元素,JAXB將它解組到另外一些東西。例如,JAXB解組無效整數
9999999999變換成1410065407.
988888888888被轉換成1046410808.
我的問題是什麼是正在這裏遵循的邏輯(公式)?
如何處理(考慮驗證將關閉)?我想要這樣的價值被拒絕。
備註:我是EclipseLink JAXB (MOXy)的領導者和JAXB (JSR-222)專家組的成員。
簡短的回答
這似乎是在JAXB參考實現中的錯誤。我建議從以下位置進入了一個bug:
此相同的情況下,使用中正常工作的EclipseLink JAXB(莫西)。
長的答案
以下是一個演示這一問題的完整的例子:
根
下面是int
和integer
場域類。
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>
演示
在演示代碼下面我就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(莫西)
如果指定莫西爲您的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
轉換。
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);
}
}
包信息
使用在封裝級的@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
更多信息
非常感謝澄清的問題!對於我們的產品,切換JAXB參考實現可能不可行,但將integer類型的元素聲明爲字符串可能是潛在的解決方案。 –
@ArnabBiswas - 你不需要製作'string'類型的元素。相反,我建議通過'XmlAdapter'提供自己的'String' /'Integer'轉換邏輯。我用一個完整的例子更新了我的答案。 –
再次感謝。對不起,我的評論不夠清楚。但是,這也是我正在考慮的。 –