簡體   English   中英

從JAXB強制轉換null java.lang.Integer會產生0,而不是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的兩個有效表示形式是:

  1. 缺少的元素,對應於XML模式中的minOccurs="0" 這是默認行為。
  2. 元素上的xsi:nil="true" 這對應於XML架構中的nillable="true" 如果使用@XmlElement(nillable=true)注釋屬性,則將獲得此行為。

UPDATE

感謝您的回答。 在第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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM