业务背景
在公司接收一个新需求。由于公司业务的需要,要采集网络设备的cpu利用率、内存利用率等性能指标。这里通过问题分析,发现通过snmp协议已经拿到了网络设备的性能指标数据,但是页面上一直显示为0。通过log日志定位问题,最终发现是一个过滤数据的方法出现的问题。
这里说明一下,老代码用的是org.apache.commons.lang包里的StringUtils.isNumeric()方法来过滤数据的。就是它,害的我搞查了三天的bug!!!下面是它的源碼,可以它
里面是用Character.isDigit()方法来判断是不是数值型数据的。
public static boolean isNumeric(String str) {
if (str == null) {
return false;
} else {
int sz = str.length();
for(int i = 0; i < sz; ++i) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
}
咱继续往下看!!!,看到没它用的是int强制类型转换。就是这里出现的问题。由于从网络设备上采集的cpu利用率、内存利用率等有可能带小数点,它这里是把字符串拆分成单个字符,然后把字符强制类型转化为int型,然后判断是不是数值。而咱采集的数据带小数点的话,它会把小数点也拆出来,判断是不是数值,如果不是就返回为false了,直接判断该数据不是数值。这样的话就把带小数点的数据给过滤掉了。因此,不能用org.apache.commons.lang包下的StringUtils.isNumeric()来判断从设备上采集的数据是不是数值型的!!!
public static boolean isDigit(char ch) {
return isDigit((int)ch);
}
公司的大佬看了后,分分钟写了个过滤数值类型的方法,这里也放一下,方便以后有相同的业务的话可以直接搬!!!
代替方法如下:
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+");
Matcher isNum = pattern.matcher(str);
if (!isNum.matches()) {
return false;
}
return true;
}