You need to enable JavaScript to run this app. 使用响应式WebClient请求StackExchange API出现JSON解码异常如何修正
优惠活动
大模型
产品
解决方案
定价
更多

使用响应式WebClient请求StackExchange API出现JSON解码异常如何修正

问题根源
  • StackExchange接口返回的items字段是数组结构,而非单个ItemsData对象,直接触发Jackson反序列化类型不匹配报错
  • 实体类使用了大量不适用于JSON解析的注解,导致序列化/反序列化结构和接口实际返回结构完全不匹配
  • 主类存在冗余的容器初始化逻辑,属于无意义重复代码
具体调整方案

1. 重构实体类

删除冗余类

直接删掉完全无用的ItemsData类,该类的结构和接口返回结构完全不匹配。

修改StackResponse类

将items字段声明为回答对象列表,匹配接口的数组结构:

@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class StackResponse {
    private List<AnswerItem> items;
}

新增AnswerItem类

对应接口返回的items数组中的每个回答元素:

@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class AnswerItem {
    // 每个回答元素直接包含owner字段
    private Owner owner;
}

修改Owner类

删除所有会增加多余包装结构的注解,匹配接口返回的owner字段结构:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Owner {
    @JsonProperty("user_id")
    private long userId;
    @JsonProperty("display_name")
    private String displayName;
    private String link;
}

注意:需删除原Owner类上的@JsonTypeName、@JsonTypeInfo注解,以及所有类上的@JacksonXmlElementWrapper注解,这些是XML解析专用注解,不适用于JSON场景。

2. WebClient逻辑调整

原有WebClient的请求逻辑无需修改,若需要直接返回List<Owner>,可在方法内增加映射逻辑:

public Mono<List<Owner>> getOwners() {
    return this.webClient
            .get()
            .uri("https://api.stackexchange.com/2.2/answers?site=stackoverflow&page=1&pagesize=5&order=desc&sort=activity&filter=default")
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(StackResponse.class)
            .map(stackResponse -> stackResponse.getItems().stream()
                    .map(AnswerItem::getOwner)
                    .collect(Collectors.toList()));
}

若仍需要返回完整的StackResponse,保留原方法即可。

3. 主类冗余逻辑清理

删除重复初始化ApplicationContext的代码,Spring Boot启动时已自动初始化容器,可直接通过依赖注入获取StackResponseClient,修改后的主类示例:

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private StackResponseClient stackResponseClient;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) {
        // 测试获取完整StackResponse对象
        StackResponse stackResponse = stackResponseClient.getOwners().block();
        System.out.println(stackResponse);

        // 若已修改getOwners方法直接返回Owner列表,可使用以下测试代码
        // List<Owner> owners = stackResponseClient.getOwners().block();
        // System.out.println(owners);
    }
}
结构匹配说明

修改后Jackson解析的结构会和接口返回结构完全对齐:

  • 顶层对象包含items数组
  • 数组每个元素为回答对象,直接包含owner字段
  • owner字段直接包含user_id、display_name、link属性,无多余嵌套包装

内容的提问来源于stack exchange,提问作者Dzikoŭski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 12:24:04