关于JSON解析中获取不存在的key问题
1 . fastjson
在fastjson中有些getXXX方法 , 如getString , getInteger , getIntValue等 , 当调用getXXX方法时 , 如果传入的key在json中不存在 , 那调用这些方法会报错抛出异常吗 ?
首先来看代码demo
public static void main(String[] args) {
String str = "{\"name\":\"Bob\",\"age\":\"18123\"}";
JSONObject jsonObject = JSON.parseObject(str);
String[] keys = { "age" , "score"};
for(String key : keys){
System.out.println(jsonObject.getString(key));
System.out.println(jsonObject.getInteger(key));
System.out.println(jsonObject.getIntValue(key));
}
}运行结果如下 :
18123
18123
18123
null
null
0
可看到 , 对不存在的key值(score)尝试进行getXXX时 , 会返回当前类型的默认值(String返回null , Integer返回null , intValue返回0)
查看getString/getInteger源码如下 :
public String getString(String key) {
Object value = get(key);
if (value == null) {
return null;
}
return value.toString();
}public Integer getInteger(String key) {
Object value = get(key);
return castToInt(value);
}getString就是调用get方法 , 然后判断为null , 为null则返回null , 否则调用对象的toString()方法.getInteger就是相当于调用get方法 , 然后调用castToInt方法将Ojbect对象转换为Integer对象 , castToInt方法如下 :
public static Integer castToInt(Object value) {
if (value == null) {
return null;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value instanceof String) {
String strVal = (String) value;
if (strVal.length() == 0 //
|| "null".equals(strVal) //
|| "NULL".equals(strVal)) {
return null;
}
if (strVal.indexOf(',') != 0) {
strVal = strVal.replaceAll(",", "");
}
return Integer.parseInt(strVal);
}
if (value instanceof Boolean) {
return ((Boolean) value).booleanValue() ? 1 : 0;
}
throw new JSONException("can not cast to int, value : " + value);
}首先看到第一个if中进行了判断 , 如果value值为null , 则直接返回null , 那getIntValue怎么判断的呢 , getIntValue源码如下 :
public int getIntValue(String key) {
Object value = get(key);
if (value == null) {
return 0;
}
return castToInt(value).intValue();
}原来在调用castToInt之前 ,就先做了一次null的判断 , 为null直接返回了0 .
那调用get方法获取一个不存在的key时 , 为什么会返回null而不是报错呢 , 查看get源码如下
public Object get(Object key) {
return map.get(key);
}map是JSONObject的一个成员变量
private final Map<String, Object> map;
原来 , JSONObject先将json字符串转换为了一个map , 而map的get方法获取不存在的key时 , 返回的就是null .
由此可以看到 , fastjson对不存在的key做了判断 , 如果没有则会返回类型的默认值 .
2 . net.sf.json
public static void main(String[] args) {
String str = "{\"name\":\"Bob\",\"age\":\"18\"}";
JSONObject jsonObject = JSONObject.fromObject(str);
// System.out.println(jsonObject.get("gender"));//null
// System.out.println(jsonObject.getString("gender"));//JSONObject["gender"] not found
// System.out.println(jsonObject.getInt("age"));//18
System.out.println(jsonObject.getInt("score"));//JSONObject["score"] is not a number
}可以看到和fastjson的处理策略不同 , 它是对不存在的key抛出一个JSONException异常 , 查看源码可以看到
public String getString(String key) {
this.verifyIsNull();
Object o = this.get(key);
if (o != null) {
return o.toString();
} else {
throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] not found.");
}
} public int getInt(String key) {
this.verifyIsNull();
Object o = this.get(key);
if (o != null) {
return o instanceof Number ? ((Number)o).intValue() : (int)this.getDouble(key);
} else {
throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");
}
}3 . org.json
和net.sf.json一样 , org.json对不存在的key策略还是抛出异常 . 但org.json更加严格 , 在使用get("key")时就会直接抛出异常
public static void main(String[] args) throws Exception {
String str = "{\"name\":\"Bob\",\"age\":\"18\"}";
JSONObject jsonObject = new JSONObject(str);
System.out.println(jsonObject.get("gender"));//No value for gender
System.out.println(jsonObject.getString("gender"));//No value for gender
System.out.println(jsonObject.getInt("age"));//18
System.out.println(jsonObject.getInt("score"));//No value for score
}get方法源码如下 :
public Object get(String name) throws JSONException {
Object result = nameValuePairs.get(name);
if (result == null) {
throw new JSONException("No value for " + name);
}
return result;
}getString源码如下 , getInt与之类似 :
public int getInt(String name) throws JSONException {
Object object = get(name);
Integer result = JSON.toInteger(object);
if (result == null) {
throw JSON.typeMismatch(name, object, "int");
}
return result;
}以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Spring Data JPA 整合QueryDSL的使用案例
QueryDSL 是一个用于构建类型安全的 SQL 查询的 Java 库,它的主要目标是简化在 Java 中构建和执行 SQL 查询的过程,同时提供类型安全性和更好的编码体验,对Spring Data JPA 整合QueryDSL使用案例感兴趣的朋友跟随小编一起看看吧2023-08-08
Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解
这篇文章主要介绍了Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-07-07
SpringBoot2中使用@RequestHeader获取请求头的方法
springMVC/SpringBoot中提供了@RequestHeader注解用来获取请求头。本文就详细的来介绍一下如何使用,感兴趣的可以了解下2021-10-10
SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法
这篇文章主要介绍了SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-07-07


最新评论