繁体   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