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

Spring WebClient处理含错误元素的JSON数组问题

问题

我需要获取一个长度为n的JSON数组,将其反序列化为n个RegistryPerson类型的对象。这个类是由XSD生成的,无法修改。JSON数组里可能包含RegistryPerson无法接受的数据(比如格式错误的日期字符串),导致反序列化失败,进而整个请求直接返回空列表。

我期望能逐个处理数组元素,反序列化失败就丢弃该元素,继续处理下一个。目前使用的代码如下:

List<RegistryPerson> registryPersons = regWebClient //this is the WebClient
            .get().uri(personerUrl(identifikatorer))
            .exchangeToFlux(r -> {
                Flux<RegistryPerson> flux;
                try {
                    log.info("Processing..");
                    flux = r.bodyToFlux(RegistryPerson.class);
                } catch (Exception e) { // e: decoding error
                    log.error("Rotten data!");
                    return Flux.empty();
                }
                return flux;
            })
            .doOnError(e -> log.error("Error: {}", e.getMessage())).onErrorResume(e -> Mono.empty())
            .collectList()
            .flatMap(Mono::just).block();

但当前代码是一次性处理整个列表,哪怕数组有多个元素,"Processing.."日志也只打印一次,而且遇到错误元素时整个流程直接失败。请问该怎么实现逐个元素处理?

解决方案

你的代码问题在于bodyToFlux(RegistryPerson.class)是一次性尝试解码整个响应流,一旦某个元素解析失败,整个Flux就会触发错误终止,而且你写的try-catch根本捕获不到异常——因为bodyToFlux是延迟执行的,不会在调用时立刻抛出错误。

要实现逐个元素处理并跳过失败项,需要先把响应解析成通用的JSON节点流,再逐个尝试转换为RegistryPerson,转换失败就跳过。具体修改如下:

ObjectMapper objectMapper = new ObjectMapper(); // 可复用项目中已有的ObjectMapper实例

List<RegistryPerson> registryPersons = regWebClient
        .get()
        .uri(personerUrl(identifikatorer))
        .exchangeToFlux(response -> response.bodyToFlux(JsonNode.class)) // 先解析为单个JSON节点的流
        .flatMap(jsonNode -> {
            try {
                // 逐个尝试将JSON节点转为RegistryPerson
                RegistryPerson person = objectMapper.treeToValue(jsonNode, RegistryPerson.class);
                return Mono.just(person);
            } catch (JsonProcessingException e) {
                log.error("解析单个元素失败,跳过该元素: {}", e.getMessage());
                return Mono.empty(); // 转换失败返回空Mono,丢弃当前元素
            }
        })
        .collectList()
        .block();

关键改动说明:

  • 拆分JSON流:用bodyToFlux(JsonNode.class)把整个JSON数组拆分成单个的JSON节点流,确保每个元素能被独立处理。
  • 单独捕获转换错误:在flatMap中对每个JsonNode单独执行转换,失败时仅跳过当前元素,不会中断整个流的处理。
  • 移除全局错误终止:去掉原来的onErrorResume,避免单个元素错误导致整个列表返回空。

这样修改后,每个元素都会被单独解析,失败的元素会被自动跳过,不会影响其他元素的处理,同时你还能针对性地记录错误元素的信息,方便后续排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:21:06