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

Spring Boot使用WebClient调用XML接口遇UnmarshalException问题求助

问题分析与解决方案

核心问题:XML命名空间不匹配

错误提示明确指出:接口返回的是带命名空间http://www.concursolutions.com/api/expense/extract/2010/02的<definitions>元素,但你的POJO类未配置对应命名空间,JAXB预期的是无命名空间的<definitions>,因此解析失败。

分步解决

1. 给POJO配置XML命名空间

你需要为Definitions和Definition类指定对应命名空间,有两种配置方式可选:

方式一:类级别单独配置
修改Definitions.java:

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@XmlRootElement(name = "definitions", namespace = "http://www.concursolutions.com/api/expense/extract/2010/02")
@XmlAccessorType(XmlAccessType.FIELD)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Definitions {
    // 移除xmlns和i字段:这两个是XML命名空间声明属性,不属于业务数据,JAXB会自动处理
    private List<Definition> definition;
}

修改Definition.java:

import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "definition", namespace = "http://www.concursolutions.com/api/expense/extract/2010/02")
public class Definition {
    private String id;
    private String name;
    // XML元素<job-link>与Java字段joblink名称不匹配,需指定映射关系
    @XmlElement(name = "job-link")
    private String joblink;
}

方式二:包级别统一配置(推荐)
在模型类所在包下创建package-info.java文件,内容如下:

@XmlSchema(
    namespace = "http://www.concursolutions.com/api/expense/extract/2010/02",
    elementFormDefault = XmlNsForm.QUALIFIED
)
package com.concur.models;

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

该配置会让包下所有JAXB类默认使用指定命名空间,无需每个类单独添加namespace属性,更简洁易维护。

2. 处理字段与XML元素的映射问题

  • XML中的<job-link>元素与Java字段joblink名称不一致,必须用@XmlElement(name = "job-link")明确映射关系,否则JAXB无法匹配。
  • 移除Definitions类中的xmlns和i字段:这两个是XML的命名空间声明属性,不属于业务数据,JAXB会自动处理命名空间逻辑,保留反而会干扰解析。

3. 关于移除@XmlAccessorType后的错误

移除@XmlAccessorType(XmlAccessType.FIELD)后出现IllegalAnnotationsException,原因是:
JAXB默认访问类型为XmlAccessType.PROPERTY(通过getter/setter访问),而Lombok的@Data注解会为public字段自动生成getter/setter,导致JAXB同时识别到public字段和对应的getter/setter,产生访问冲突。保留@XmlAccessorType(XmlAccessType.FIELD)可让JAXB直接通过字段访问,避免该冲突,因此这个注解是必需的。

验证修改

完成上述修改后,原WebClient调用代码无需改动,重新测试即可正常将XML响应解析为Java POJO。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:33:24