You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从SOAP请求消息中获取Integer类型的null对象?

如何将SOAP请求中空的dateOfBirth子字段映射为Java Integer类型的null值

问题场景

作为SOAP技术新手,收到如下SOAP请求片段,其中dateOfBirth下的year、month、day均为空标签:

<patient>
    <dateOfBirth>
        <year></year>
        <month></month>
        <day></day>
    </dateOfBirth>
    <firstName>Ivan</firstName>
    <lastName>Luku</lastName>       
</patient>

对应的XSD Schema片段定义如下:

xs:complexType name="personVO">
<xs:complexContent>
<xs:extension base="tns:tenantableVO">
<xs:sequence>
<xs:element name="dateOfBirth" type="tns:localDateVO"/>
<xs:element name="firstName" type="xs:string"/>
<xs:element name="lastName" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>

------------------------------------------
<xs:complexType name="localDateVO">
<xs:sequence>
<xs:element name="day" type="xs:int" nillable="true" minOccurs="0"/>
<xs:element name="month" type="xs:int" nillable="true" minOccurs="0"/>
<xs:element name="year" type="xs:int" nillable="true" minOccurs="0"/>
</xs:sequence>
</xs:complexType>

上述字段在Java代码中为Integer类型,期望接收请求后这些空字段能映射为null值,但之前的尝试遇到了问题:

  • 在get方法上添加@XmlAttribute注解无效,无论字段是否有值都返回null:
@XmlAttribute
public Integer getDay() {
    return day;
}
@XmlAttribute
public Integer getMonth() {
    return month;
}
@XmlAttribute
public Integer getYear() {
    return year;
}
  • 尝试在字段上添加相同注解时,出现Class has two properties of the same name错误。

解决方案

1. 替换注解类型,使用@XmlElement匹配XSD定义

XSD中day、month、year是<xs:sequence>下的子元素,并非XML属性,因此不能使用@XmlAttribute,需改用@XmlElement并配置与XSD一致的属性:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(name = "localDateVO", propOrder = {"day", "month", "year"})
public class LocalDateVO {
    private Integer day;
    private Integer month;
    private Integer year;

    @XmlElement(nillable = true, required = false)
    public Integer getDay() {
        return day;
    }

    public void setDay(Integer day) {
        this.day = day;
    }

    @XmlElement(nillable = true, required = false)
    public Integer getMonth() {
        return month;
    }

    public void setMonth(Integer month) {
        this.month = month;
    }

    @XmlElement(nillable = true, required = false)
    public Integer getYear() {
        return year;
    }

    public void setYear(Integer year) {
        this.year = year;
    }
}

nillable=true对应XSD中的nillable="true",required=false对应minOccurs="0",确保JAXB正确识别字段的可空特性。

2. 自定义适配器处理空标签到null的转换

若空标签仍未映射为null(JAXB默认会将空元素解析为空字符串,而Integer类型无法直接转换),可添加自定义适配器:
首先创建适配器类:

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class EmptyStringToNullIntegerAdapter extends XmlAdapter<String, Integer> {
    @Override
    public Integer unmarshal(String v) throws Exception {
        if (v == null || v.trim().isEmpty()) {
            return null;
        }
        return Integer.parseInt(v);
    }

    @Override
    public String marshal(Integer v) throws Exception {
        return v != null ? v.toString() : null;
    }
}

然后在对应的get方法上添加适配器注解:

@XmlElement(nillable = true, required = false)
@XmlJavaTypeAdapter(EmptyStringToNullIntegerAdapter.class)
public Integer getYear() {
    return year;
}
// month和day字段的get方法同理添加该注解

3. 解决重复属性错误

出现Class has two properties of the same name是因为JAXB默认同时识别字段和get/set方法作为属性,导致重复,可通过以下两种方式解决:

  • 只在字段上添加注解,并给类添加@XmlAccessorType(XmlAccessType.FIELD),指定JAXB仅通过字段访问属性:
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "localDateVO", propOrder = {"day", "month", "year"})
public class LocalDateVO {
    @XmlElement(nillable = true, required = false)
    private Integer day;
    @XmlElement(nillable = true, required = false)
    private Integer month;
    @XmlElement(nillable = true, required = false)
    private Integer year;

    // 保留get/set方法但无需添加注解
    public Integer getDay() {
        return day;
    }

    public void setDay(Integer day) {
        this.day = day;
    }

    // 其他get/set方法同理
}
  • 或者仅在get方法上添加注解,字段上不添加注解,避免JAXB重复识别。

内容的提问来源于stack exchange,提问作者ivashchenko_ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:12:55