Jsonobject 類getInteger函數取值異常

產品實驗局環境同事發現分佈圖與實際業務對不上,由於頁面展現流量較大的RTSP,客戶並無相關APP業務。起初覺得是前端業務邏輯出問題了:前端

查看前端數據庫查詢代碼,邏輯十分簡單,從數據庫中獲取app字段的值,而後對應app字典,前端展現:python

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]

 

部分字典示例:sql

    <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中的邏輯出現問題了。數據庫

數據庫這個表其餘字段都沒有錯,就是這個字段取值錯了:json

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 | 52app

查看數據寫數據庫的代碼,發現app這個值定義int,以前若是數據超過int,應該是溢出爲負值了,爲何給了一個0-10的整數值呢?ide

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:post

{"app":16026481486462977}
1  

 

繼續查看這個函數的方法:spa

    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得以發現並解決。

相關文章
相關標籤/搜索