[英]Passing empty string to .tag with a java.lang.Integer attribute results in 0 (not null)
[英]Casting null java.lang.Integer from JAXB produces 0, not null
我有以下XML:
<person>
<id/>
<Identifier/>
<Surname>TEST</Surname>
<Forename1>TEST</Forename1>
<Forename2/>
<Title>MR</Title>
<Gender>M</Gender>
</person>
通過序列化以下類產生:
package anonymised.packagename;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"Id",
"Identifier",
"Surname",
"Forename1",
"Forename2",
"Title",
"Sex"
})
@XmlRootElement(name = "person")
public class person{
@XmlElement(name = "id", nillable=true)
protected Integer Id;
public Integer getId(){
return Id;
}
public void setId(Integer value){
this.Id = value;
}
@XmlElement(name = "Identifier", nillable=true)
protected String Identifier;
public String getIdentifier(){
return Identifier;
}
public void setIdentifier(String value){
this.Identifier = value;
}
@XmlElement(name = "Surname", nillable=true)
protected String Surname;
public String getSurname(){
return Surname;
}
public void setSurname(String value){
this.Surname = value;
}
@XmlElement(name = "Forename1", nillable=true)
protected String Forename1;
public String getForename1(){
return Forename1;
}
public void setForename1(String value){
this.Forename1 = value;
}
@XmlElement(name = "Forename2", nillable=true)
protected String Forename2;
public String getForename2(){
return Forename2;
}
public void setForename2(String value){
this.Forename2 = value;
}
@XmlElement(name = "Title", nillable=true)
protected String Title;
public String getTitle(){
return Title;
}
public void setTitle(String value){
this.Title = value;
}
@XmlElement(name = "Gender", nillable=true)
protected String Gender;
public String getGender(){
return Gender;
}
public void setGender(String value){
this.Gender = value;
}
}
我使用對象上的“設置”方法和JAXB序列化生成上面的XML,正是由於它們是可空的,因此選擇java.lang.Integer對象。
然后,我使用以下代碼將XML(由xmlString表示)反序列化回該對象:
DocumentBuilder builder = fac.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
String className = "anonymised.packagename." + doc.getDocumentElement().getNodeName();
Class<?> c = Class.forName(className);
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller um = context.createUnmarshaller();
Object o = c.cast(um.unmarshal(new StringReader(xmlString)));
JAXBContext jbc = JAXBContext.newInstance(c);
Marshaller jm = jbc.createMarshaller();
jm.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jm.marshal(o, new File("C:\\person.xml"));
產生了以下XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id>0</id>
<Identifier/>
<Surname>TEST</Surname>
<Forename1>TEST</Forename1>
<Forename2></Forename2>
<Title>MR</Title>
<Gender>M</Gender>
</person>
現在為null的java.lang.Integer為0。這怎么可能? 從斷點來看,在轉換過程中會發生從null到0的更改,但是我不知道為什么會這樣。 在轉換過程中是否有某種轉換為簡單int的方法? 有辦法避免這種現象嗎? 我認為在XML Element聲明中添加“ nillable”會有所幫助,但沒有幫助。
JAXB認為任何空元素都不是null
的有效表示形式。 如果您indentifier
String
類型的indentifier
屬性進行內省,則在解組空元素后會看到它是""
。
null的兩個有效表示形式是:
minOccurs="0"
。 這是默認行為。 xsi:nil="true"
。 這對應於XML架構中的nillable="true"
。 如果使用@XmlElement(nillable=true)
注釋屬性,則將獲得此行為。 感謝您的回答。 在第2點上,我在上面的類中用@XmlElement(nillable = true)注釋了我的屬性,但是我沒有您在XML中描述的行為。 您的答案是否意味着在生成任何應該為null的XML時,需要將屬性xsi:nil顯式設置為true?
當您擁有@XmlElement(nillable=true)
,期望的是相應的XML元素將xsi:nil
屬性設置為true
,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</person>
我對Identifier元素是一個空String而不是null而是id元素的想法感到滿意,因為它是一個Integer應該為null而不是0,對吧?
您絕對可以提出該論點。 使用JAXB RI,如果將Integer
屬性更改為Long
您將看到所需的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.