注: 私は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;
}
input.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
出力-EclipseLinkJAXB(MOXy)
JAXBプロバイダーとしてMOXyを指定した場合(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
to/fromString
変換を行うためのを作成できます。
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
詳細については