使用WebClient获取第三方嵌套JSON后,如何提取generalDetails并找首个true值?
解决方案
先优化你的WebClient请求(避免多余的字符串转义)
Spring WebClient可以直接把响应解析为Jackson的JsonNode,省去先转成String再二次解析的步骤,更高效:
@Autowired private WebClient.Builder webClientBuilder; // 直接解析为JsonNode,无需转String JsonNode responseJson = webClientBuilder.build().get().uri(URL) .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(JsonNode.class) .block();
定位到generalDetails节点
用path()方法(比get()更安全,不存在的节点会返回空节点而非抛异常)逐层定位目标节点:
// 逐层定位到generalDetails JsonNode generalDetails = responseJson.path("data") .path("failure_data") .path("details") .path("data") .path("server_response") .path("generalDetails");
按指定顺序查找第一个"true"值
严格按照security→address→account→mobile的优先级遍历模块,每个模块内遍历字段,找到第一个值为"true"的键值对就立即终止遍历:
import com.fasterxml.jackson.databind.JsonNode; import java.util.Arrays; import java.util.List; // 定义模块遍历的优先级顺序 List<String> modulePriority = Arrays.asList("security", "address", "account", "mobile"); // 存储找到的第一个true的模块和字段信息 String firstTrueModule = null; String firstTrueField = null; for (String moduleName : modulePriority) { JsonNode moduleNode = generalDetails.path(moduleName); // 跳过不存在或为空的模块节点 if (moduleNode.isMissingNode() || moduleNode.isNull() || !moduleNode.isObject()) { continue; } // 遍历当前模块下的所有字段 for (String fieldName : moduleNode.fieldNames()) { String fieldValue = moduleNode.path(fieldName).asText(); if ("true".equalsIgnoreCase(fieldValue)) { firstTrueModule = moduleName; firstTrueField = fieldName; // 找到第一个匹配项后直接跳出所有循环 break; } } if (firstTrueField != null) { break; } } // 结果输出示例 if (firstTrueField != null) { System.out.printf("找到第一个true值:模块=%s,字段=%s%n", firstTrueModule, firstTrueField); } else { System.out.println("未找到任何true值"); }
关键说明
- 容错性:用
path()替代get(),避免第三方API结构变动导致的空指针异常 - 优先级保证:严格按照你指定的模块顺序查找,确保返回的是优先级最高的第一个true值
- 兼容性:适配示例中
true为字符串类型的情况(若API后续返回布尔值,只需把"true".equalsIgnoreCase(fieldValue)改为moduleNode.path(fieldName).asBoolean()即可) - 效率优化:找到匹配项后立即终止所有遍历,避免无效计算
内容的提问来源于stack exchange,提问作者Andres
相关产品推荐
相关产品推荐

