Примечание. Я 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
Вывод – EclipseLink JAXB (MOXy)
Если вы укажете MOXy в качестве поставщика 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
Для получения дополнительной информации
person
bdoughan
schedule
04.11.2012