JAXB Unmarshaller反序列化SOAP响应时字段返回null如何解决
问题排查与修复方案
1. 核心错误:类名不匹配
你定义的SOAP响应映射POJO类名声明为GetOrderResponse,但反序列化逻辑中JAXBContext初始化、结果接收全使用了不存在/不匹配的CreateOrderResponse类,直接导致反序列化后字段无法正常映射。
先修正POJO类名:
package per.me.soapclient.response; import jakarta.xml.bind.annotation.*; import lombok.Getter; @XmlRootElement(name = "CreateOrderResponse", namespace = "https://myns.com") @XmlType(propOrder = {"orderID"}) @XmlAccessorType(XmlAccessType.FIELD) @Getter // 类名和反序列化使用的类名保持一致 public class CreateOrderResponse { @XmlElement(name = "OrderID", namespace = "https://myns.com") public Long orderID; }
2. 修正反序列化逻辑
直接对SOAPBody反序列化可能会因为节点层级问题映射失败,建议先提取Body内的目标响应节点再做反序列化:
try { final MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); final JAXBContext jaxbContext = JAXBContext.newInstance(CreateOrderResponse.class); final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); try(ByteArrayInputStream bais = new ByteArrayInputStream(soapXML.getBytes(StandardCharsets.UTF_8))) { final SOAPMessage soapMessage = messageFactory.createMessage(new MimeHeaders(), bais); SOAPBody soapBody = soapMessage.getSOAPBody(); // 先定位到CreateOrderResponse节点再反序列化 Node responseNode = soapBody.getChildElements(new QName("https://myns.com", "CreateOrderResponse")).next(); CreateOrderResponse response = unmarshaller.unmarshall(responseNode, CreateOrderResponse.class).getValue(); Assertions.assertEquals(100100L, response.getOrderID()); } } catch (SOAPException | JAXBException | IOException e) { throw new IllegalStateException(e); }
3. 可选优化
你已经在package-info.java中配置了全局命名空间规则,POJO类上的namespace属性可以省略,简化注解写法:
@XmlRootElement(name = "CreateOrderResponse") @XmlType(propOrder = {"orderID"}) @XmlAccessorType(XmlAccessType.FIELD) @Getter public class CreateOrderResponse { @XmlElement(name = "OrderID") public Long orderID; }
内容的提问来源于stack exchange,提问作者thisisshantzz
相关产品推荐
相关产品推荐

