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

JAXB反序列化SOAP XML绑定POJO时字段全为null问题求助

JAXB反序列化SOAP报文全字段为null修复方案

核心问题是命名空间配置缺失+注解映射错误+代码笔误三类问题叠加,逐个修正即可:

  • 所有业务节点都属于默认命名空间urn:soap.origin.com,但除根类外其余实体、字段都未指定该命名空间,JAXB默认按空命名空间匹配节点,就算name写对也找不到对应值
  • 注解存在大量语法错误、映射值错误:部分@XmlElement的name属性漏写前引号、Json注解名写错、字段名和XML标签不匹配、漏写报文里存在的字段
  • 解析方法存在变量名笔误,编译都无法通过

修复步骤

1. 统一配置命名空间(最省事方案)

在所有JAXB实体类所在的包下新建package-info.java文件,统一指定包下所有类的默认命名空间,不用每个注解单独写namespace属性:

@XmlSchema(
        namespace = "urn:soap.origin.com",
        elementFormDefault = XmlNsForm.QUALIFIED
)
// 下面替换成你自己的实体类实际包路径
package com.your.project.entity;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

如果不想加包级配置,就给每个实体类、每个@XmlElement注解都加上namespace = "urn:soap.origin.com"属性,效果一致但写法繁琐

2. 修正EventResponse类

补全注解漏写的引号,修正result字段的错误映射:

@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "eventResponse", namespace = "urn:soap.origin.com")
public class EventResponse{
    // 原代码name写的是LoginResult,和实际XML标签result完全不匹配
    @XmlElement(name = "result")
    private Result result;
}

3. 修正Result类

修正写错的Json注解,补全报文中存在的boolean1字段,修正userInfo字段的映射值:

@Getter
@Setter
// 原代码多写了一层Json前缀,注解名写错
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlAccessorType(XmlAccessType.FIELD)
public class Result{

    @XmlElement(name="field1", nillable="true")
    private String field1;

    // 原代码漏写该字段,错把属于userInfo的boolean2写到了这
    @XmlElement(name="boolean1")
    private Boolean boolean1;

    @XmlElement(name="userId", nillable="true")
    private String userId;

    // 原代码name写的是类型名GetUserInfo,要和实际XML标签名一致,你提供的报文里是全小写userinfo
    @XmlElement(name="userinfo")
    private UserInfo userInfo;
}

如果实际返回报文里该节点是驼峰userInfo,把上面的name值改成对应值即可,永远以实际返回的XML标签名为准

4. 修正UserInfo类

修正写错的Json注解,保证字段和XML标签一一对应:

@Getter
@Setter
// 原代码多写了一层Json前缀,注解名写错
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlAccessorType(XmlAccessType.FIELD)
public class UserInfo{

    @XmlElement(name="boolean2")
    private Boolean boolean2;

    @XmlElement(name="field2", nillable="true")
    private String field2;

    @XmlElement(name="orgId")
    private String orgId;

    @XmlElement(name="userCode", nillable=true)
    private String userCode;
}

5. 修正解析方法的笔误

统一变量名,指定报文编码避免乱码:

private EventResponse parseXmlResult(String xmlToParse) throws Exception {
    JAXBContext jaxbContext = JAXBContext.newInstance(EventResponse.class);
    // 原代码变量定义为msg,后面调用时写成了message,属于低级笔误;指定UTF-8编码避免乱码
    SOAPMessage msg = MessageFactory.newInstance().createMessage(null, 
            new ByteArrayInputStream(xmlToParse.getBytes(StandardCharsets.UTF_8)));
    Unmarshaller um = jaxbContext.createUnmarshaller();
    EventResponse response = (EventResponse) um.unmarshall(msg.getSOAPBody().extractAsDocument());
    return response;
}

额外排查点

你提供的示例XML里SOAP Envelope标签前缀写的是soap:env,但实际声明的命名空间前缀是soapenv,前缀不匹配会导致SOAPMessage解析直接报错,如果是你写示例时的手误可以忽略,实际运行时要保证报文前缀和声明的命名空间前缀一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:15:38