Jsonobject 类getInteger函数取值异常

Posted cleaver

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jsonobject 类getInteger函数取值异常相关的知识,希望对你有一定的参考价值。

产品实验局环境同事发现分布图与实际业务对不上,因为页面展示流量较大的RTSP,客户并没有相关APP业务。起初以为是前端业务逻辑出问题了:

查看前端数据库查询代码,逻辑十分简单,从数据库中获取app字段的值,然后对应app字典,前端展示:

APP_DICT = get_app_dict()
result = {"list": {}}
if len(data) != 0:
for i in range(len(data)):
     if data[i][1] in APP_DICT:
           result["list"][APP_DICT[data[i][1]]] = data[i][0]

 

部分字典示例:

    <platform display_name="RTSP" id="1" name="RTSP" name_en_US="RTSP" name_zh_CN="RTSP" name_zh_TW="RTSP">
      <app category="media" display_name="RTSP" id="9209509394251777" name="RTSP" name_en_US="RTSP" name_zh_CN="RTSP" name_zh_TW="RTSP" risk="1" subcategory="photo-video" tags="exband|tunnel|widely" technology="cs"/>
    </platform>
    <platform display_name="联众" id="2" name="联众" name_en_US="Ourgame" name_zh_CN="联众" name_zh_TW="聯眾">
      <app category="media" display_name="联众游戏" id="1354598325420033" name="联众游戏" name_en_US="Ourgame" name_zh_CN="联众游戏" name_zh_TW="聯眾遊戲" risk="1" subcategory="game" tags="exband|widely" technology="bs"/>
      <app category="co" display_name="联众好友" id="1354598325420034" name="联众好友" name_en_US="OurFriend" name_zh_CN="联众好友" name_zh_TW="聯眾好友" risk="1" subcategory="im" tags="

前端没问题,肯定是数据逻辑统计有问题,查看hive中数据正常,kafka中的原始数据也正常,猜想有可能是写postgresql中的逻辑出现问题了。

数据库这个表其他字段都没有错,就是这个字段取值错了:

id | alert_time | process_time | protocol | app | app_proto | bytesall | packetsall
---------+------------+--------------+----------+-----+-----------+------------+------------
897737 | 1527704580 | 1527704640 | 6 | 2 | 100 | 7150 | 32
897772 | 1527704520 | 1527704700 | 6 | 0 | 8 | 6966 | 112
897773 | 1527704640 | 1527704700 | 6 | 0 | 8 | 1344022 | 2465
897774 | 1527704580 | 1527704700 | 6 | 0 | 8 | 232312 | 864
897775 | 1527704340 | 1527704700 | 6 | 0 | 8 | 56384 | 166
897776 | 1527704640 | 1527704700 | 17 | 4 | 31 | 552 | 6
897777 | 1527704700 | 1527704700 | 6 | 0 | 8 | 107814 | 776
897778 | 1527704400 | 1527704700 | 6 | 0 | 8 | 12524 | 52

查看数据写数据库的代码,发现app这个值定义int,之前如果数据超过int,应该是溢出为负值了,为什么给了一个0-10的整数值呢?

JSONObject newObject = new JSONObject();
newObject.put("tablename", key);
for (String[] field : fieldList) {
fieldName = field[0];
fieldType = field[1];
if(fieldType.equals("String")){
newObject.put(fieldName,obj.getString(fieldName));
}else if(fieldType.equals("long")){
newObject.put(fieldName,obj.getLong(fieldName));
}else{
newObject.put(fieldName,obj.getInteger(fieldName));
}
}
return newObject.toJSONString().getBytes();

这里通过jsonobject 获取参数的值,如果是int类型的,直接根据getInteger获取值:

public class Test {
    public static void main(String[] args) {
        String data = "{app:16026481486462977}";
        JSONObject newObject = JSON.parseObject(data);
        System.out.println(newObject);
        System.out.println(newObject.getInteger("app"));
    }
}

定义了一个app的正常值,通过getInteger函数获取,果然返回了1:

{"app":16026481486462977}
1  

 

继续查看这个函数的方法:

    public Integer getInteger(String key) {
        Object value = get(key);

        return castToInt(value);
    }

发现调用了castToInt方法,应该是直接返回了int值,继续看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);
    }

这个方法实际是解决了所有异常场景,如果为int直接返回,如果为其他Number类型的值,直接调用Number 类的intValue方法:

查看JDK对该方法的描述,是强制将Number类型的值转为了int:

到这里原因应该是找到了,改为getLong,修改数据库该字段的类型为Bigint类型,再次启动入库的spark JOB:

id | alert_time | process_time | protocol | app | app_proto | bytesall | packetsall
----+------------+--------------+----------+-------------------+-----------+-----------+------------
1 | 1528426860 | 1528426980 | 17 | 2040693581152257 | 0 | 990 | 11
2 | 1528426920 | 1528426980 | 17 | 2040693581152257 | 0 | 1170 | 13
3 | 1528426860 | 1528426980 | 17 | 4582764464570369 | 21 | 411 | 5
4 | 1528426920 | 1528426980 | 17 | 4582764464570369 | 21 | 160 | 2
5 | 1528426860 | 1528426980 | 17 | 16026481486462977 | 0 | 184 | 2
6 | 1528426860 | 1528426980 | 6 | 4037406697193473 | 20 | 92 | 27
7 | 1528426560 | 1528426980 | 6 | 3087428650795009 | 8 | 9128 | 33
8 | 1528426920 | 1528426980 | 6 | 4037406697193473 | 20 | 414 | 83
9 | 1528426920 | 1528426980 | 6 | 3087428650795009 | 8 | 24654 | 78
10 | 1528426860 | 1528426980 | 6 | 3087428650795009 | 8 | 68500 | 122
11 | 1528426920 | 1528426980 | 17 | 6157265115545601 | 0 | 7888 | 102
12 | 1528426920 | 1528426980 | 6 | 27637324275777538 | 0 | 307 | 10
13 | 1528423020 | 1528426980 | 6 | 4037406697193473 | 20 | 46 | 8

取值正常,bug得以发现并解决。

 

以上是关于Jsonobject 类getInteger函数取值异常的主要内容,如果未能解决你的问题,请参考以下文章

为啥 int num = Integer.getInteger("123") 会抛出 NullPointerException?

区分Integer.getInteger和Integer.valueOfInteger.parseInt() 的使用方法

python数据取整

JSONObject optString或者getString方法取null问题

22. 平面列表

Animator 笔记