Забележка: Аз съм 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
преобразувания.
Integer Adapter
По-долу е даден пример за 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