使用流从JSON提取键值对:Java代码返回false问题排查
问题原因
你的代码一直返回false,核心问题出在Jackson的JsonNode.asBoolean()方法的行为上:
- 你的JSON里
Child1的值是字符串类型的"TRUE",但asBoolean()对字符串的判断很严格——只有当字符串是**全小写的"true"**时才会返回true,其他字符串(包括大写的"TRUE")都会返回false; - 另外,
asBoolean()永远不会返回null,所以你加的filter(Objects::nonNull)根本起不到过滤作用,等于白写。
修复方法
给你几个可行的修复方案,按需选择:
方案1:转字符串后再处理布尔值
先把JsonNode转成字符串,用Boolean.parseBoolean()处理(这个方法会忽略大小写,"TRUE"/"true"/"True"都能识别为true):
final var content = Jackson.getObjectMapper().readTree(//json link); return Stream.concat( Optional.ofNullable(content.at("/Parent1/Child1")).stream(), Optional.ofNullable(content.at("/Parent2/Child1")).stream()) .filter(JsonNode::isTextual) // 先确保是字符串类型,避免非字符串节点报错 .map(JsonNode::textValue) .map(Boolean::parseBoolean) .findFirst() .orElse(false);
如果需要保留原布尔值(比如Child1可能是"FALSE",你要返回false而不是跳过),就去掉.filter(b -> b)这一行。
方案2:用Jackson的类型转换更靠谱
直接用Jackson的convertValue方法把节点转成Boolean类型,它能正确识别大小写的字符串布尔值,甚至原生JSON布尔值也能处理:
final var content = Jackson.getObjectMapper().readTree(//json link); ObjectMapper mapper = Jackson.getObjectMapper(); return Stream.concat( Optional.ofNullable(content.at("/Parent1/Child1")).stream(), Optional.ofNullable(content.at("/Parent2/Child1")).stream()) .map(node -> mapper.convertValue(node, Boolean.class)) .filter(Objects::nonNull) .findFirst() .orElse(false);
方案3:不用Stream,直接顺序判断
如果只是按Parent1→Parent2的顺序找,其实不用Stream更简单易懂:
final var content = Jackson.getObjectMapper().readTree(//json link); // 先查Parent1的Child1 JsonNode parent1Child = content.at("/Parent1/Child1"); if (parent1Child != null && parent1Child.isTextual()) { return Boolean.parseBoolean(parent1Child.textValue()); } // 再查Parent2的Child1 JsonNode parent2Child = content.at("/Parent2/Child1"); if (parent2Child != null && parent2Child.isTextual()) { return Boolean.parseBoolean(parent2Child.textValue()); } // 都没找到返回false return false;
内容的提问来源于stack exchange,提问作者Saad
相关产品推荐
相关产品推荐

