我正在尝试在 Spring Boot 应用程序中使用 WebClient 调用返回 XML 响应的 API。我确信我收到了 API 调用的 200,但代码无法将响应解析为 Java POJO(定义)。我收到如下错误
threw exception [Request processing failed: org.springframework.core.codec.DecodingException: Could not unmarshal XML to class com.intel.eae.expenseautomationengine.concur.models.Definitions] with root cause
jakarta.xml.bind.UnmarshalException: unexpected element (uri:"http://www.concursolutions.com/api/expense/extract/2010/02", local:"definitions"). Expected elements are <{}definition>,<{}definitions>
下面是我的代码片段
使用WebClient调用API
String definitionURL = "/api/expense/extract/v1.0";
Definitions definitions = webClient
.get()
.uri(definitionURL)
.accept(MediaType.APPLICATION_XML)
.headers(httpHeaders -> httpHeaders.setBearerAuth("<<AUTH>>"))
.retrieve()
.bodyToMono(Definitions.class)
.block();
log.info("Response is {}", definitions);
WebClient Bean 配置
@Bean
public WebClient webClient() {
return WebClient.builder()
.exchangeStrategies(
ExchangeStrategies.builder()
.codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder()))
.build())
.baseUrl(concurApiURL)
.build();
}
我的响应模型(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")
@XmlAccessorType(XmlAccessType.FIELD)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Definitions {
public List<Definition> definition;
public String xmlns;
public String i;
}
定义.java
import jakarta.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "definition")
public class Definition {
private String id;
private String name;
private String joblink;
}
最后是来自 API 的响应 XML
<definitions xmlns="http://www.concursolutions.com/api/expense/extract/2010/02" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<definition>
<id>https://us2.concursolutions.com/api/expense/extract/v1.0/gWur87rvH6sJ7PAGiQwjZXFeYCXObXKvVow</id>
<name>ADV AP/GL Extract V.2.4.3</name>
<job-link>https://us2.concursolutions.com/api/expense/extract/v1.0/gWur87rvH6sJ7PAGiQwjZXFeYCXObXKvVow/job</job-link>
</definition>
</definitions>
当我删除线时
@XmlAccessorType(XmlAccessType.FIELD)
从我的定义模型中,我得到了如下不同的错误
org.glassfish.jaxb.runtime.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
我花了几个小时试图弄清楚这里出了什么问题。任何帮助将不胜感激
我能够通过在我的 java 包文件夹中使用 @XmlSchema 注释添加带有命名空间定义的 package-info.java 来添加上述工作,从而实现上述工作。
类似下面的内容
@XmlSchema(
namespace = "http://www.concursolutions.com/api/expense/extract/2010/02",
elementFormDefault = XmlNsForm.QUALIFIED
)
package com.concur.models.xml;