使用Jackson时解析json时,经常会使用jsonPath直接获取某一节点下的值,这种方式非常直观 ,例如:
{
“data”: {
"test1": "value1",
"test2": null,
"test3": 10
}
}
以Jackson2.13.5,使用at(jsonPtrExp)这种API,解析json的代码:
ObjectMapper objectMapper = new ObjectMapper();String content = "{"data": {\"test1\": \"value1\",\"test2\": null,\"test3\": 10}}";JsonNode root = objectMapper.readTree(content);JsonNode node = root.at("/data/test1");node.asText(); # 1
node.textValue(); # 2
这里有个让人疑惑的地方,获取其中的值时,到底应该用#1还是#2。
我们写一个测试用例,来看看它们的区别:
import java.io.IOException;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;public class JacksonTester {public static void main(String[] args) throws IOException {ObjectMapper objectMapper = new ObjectMapper();String content = "{"data": {\"test1\": \"value1\",\"test2\": null,\"test3\": 10}}";JsonNode root = objectMapper.readTree(content);{JsonNode node = root.at("/data/test1");System.out.println("node.isMissingNode()##" + node.isMissingNode());System.out.println("node.isNull()##" + node.isNull());System.out.println("node.asText() == null##" + (node.asText() == null));System.out.println("node.asText()##" + node.asText());System.out.println("node.textValue() == null##" + (node.textValue() == null));System.out.println("node.textValue()##" + node.textValue());System.out.println("-------------");}{JsonNode node = root.at("/data/test2");System.out.println("node.isMissingNode()##" + node.isMissingNode());System.out.println("node.isNull()##" + node.isNull());System.out.println("node.asText() == null##" + (node.asText() == null));System.out.println("node.asText()##" + node.asText());System.out.println("node.textValue() == null##" + (node.textValue() == null));System.out.println("node.textValue()##" + node.textValue());System.out.println("-------------");}{JsonNode node = root.at("/data/test3");System.out.println("node.isMissingNode()##" + node.isMissingNode());System.out.println("node.isNull()##" + node.isNull());System.out.println("node.asText() == null##" + (node.asText() == null));System.out.println("node.asText()##" + node.asText());System.out.println("node.textValue() == null##" + (node.textValue() == null));System.out.println("node.textValue()##" + node.textValue());System.out.println("-------------");}{JsonNode node = root.at("/data/test4");System.out.println("node.isMissingNode()##" + node.isMissingNode());System.out.println("node.isNull()##" + node.isNull());System.out.println("node.asText() == null##" + (node.asText() == null));System.out.println("node.asText()##" + node.asText());System.out.println("node.textValue() == null##" + (node.textValue() == null));System.out.println("node.textValue()##" + node.textValue());System.out.println("-------------");}}}
执行结果:
node.isMissingNode()##false
node.isNull()##false
node.asText() == null##false
node.asText()##value1
node.textValue() == null##false
node.textValue()##value1
-------------
node.isMissingNode()##false
node.isNull()##true
node.asText() == null##false
node.asText()##null
node.textValue() == null##true
node.textValue()##null
-------------node.isMissingNode()##false
node.isNull()##true
node.asText() == null##false
node.asText()##10
node.textValue() == null##true
node.textValue()##null
-------------
node.isMissingNode()##true
node.isNull()##false
node.asText() == null##false
node.asText()##
node.textValue() == null##true
node.textValue()##null
-------------
从执行结果中可以看到
节点值为null时 | 节点不存在时 | 节点值为字符串时 | 节点值不为字符串时 | |
asText() | “null” | "" | "value1" | "10" |
textValue() | null | null | "value1" | null |
从结果上看,如果要使用asText() ,应该是要先做如下判断
if (!node.isMissingNode() && !node.isNull())
{String value = node.asText();
}
如果是使用textValue() ,只要节点值的类型是字符串,不用判断isMissingNode()和node.isNull(),就可以直接使用。