2012-11-04 21 views
4

在我們的產品中我們使用apache CXF。由於性能限制,模式驗證已設置爲false。現在,如果我提供了一個無效值,那麼對於一個整數元素,JAXB將它解組到另外一些東西。例如,JAXB解組無效整數

9999999999變換成141006540​​7.

988888888888被轉換成1046410808.

我的問題是什麼是正在這裏遵循的邏輯(公式)?

如何處理(考慮驗證將關閉)?我想要這樣的價值被拒絕。

回答

7

備註:我是EclipseLink JAXB (MOXy)的領導者和JAXB (JSR-222)專家組的成員。

簡短的回答

這似乎是在JAXB參考實現中的錯誤。我建議從以下位置進入了一個bug:

此相同的情況下,使用中正常工作的EclipseLink JAXB(莫西)。


長的答案

以下是一個演示這一問題的完整的例子:

下面是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> 

演示

在演示代碼下面我就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值是nullValidationEvents按預期生產。

java.lang.NumberFormatException: For input string: "9999999999" 
java.lang.NumberFormatException: For input string: "988888888888" 
1410065407 
1046410808 
null 
null 

更多信息

+1

非常感謝澄清的問題!對於我們的產品,切換JAXB參考實現可能不可行,但將integer類型的元素聲明爲字符串可能是潛在的解決方案。 –

+1

@ArnabBiswas - 你不需要製作'string'類型的元素。相反,我建議通過'XmlAdapter'提供自己的'String' /'Integer'轉換邏輯。我用一個完整的例子更新了我的答案。 –

+0

再次感謝。對不起,我的評論不夠清楚。但是,這也是我正在考慮的。 –