JSON使用的小坑:JSON把带有逗号的数字字符串转为数字
起因是项目中需要前端传入id的数组,后端使用JSON接收,而前端处理错误而将id用逗号拼接后再封装成数组,如
{“ids”:[“1053,1054”]}
此处ids是一个长度为1,元素是字符串"1053,1054"的数组。
在java中使用JSONArray的toJavaList(Long.class)转为Long类型的列表,预想中这种情况应该会发生NumberFormatException,但是实际上并没有,看下下面的代码
public static void main(String[] args) {
JSONArray ids = new JSONArray();
ids.add("1053,1054");
System.out.println(ids);
System.out.println(ids.toJavaList(Long.class));
}
["1053,1054"]
[10531054]
如上,结果把1053和1054拼接起来返回了一个[10531054],这并不是我想要的。同样我也测试了JSONObject的getLong()
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", "1053,1054");
System.out.println(jsonObject.getLong("id"));
}
10531054
果然结果是一样的。进入源码发现它们都走到了TypeUtil.castToLong(Object value)方法,其中对于字符串类型的value是这样处理的
if (value instanceof String) {
String strVal = (String)value;
if (strVal.length() == 0 || "null".equals(strVal) || "NULL".equals(strVal)) {
return null;
}
if (strVal.indexOf(44) != -1) {
strVal = strVal.replaceAll(",", "");
}
try {
return Long.parseLong(strVal);
} catch (NumberFormatException var4) {
JSONScanner dateParser = new JSONScanner(strVal);
Calendar calendar = null;
if (dateParser.scanISO8601DateIfMatch(false)) {
calendar = dateParser.getCalendar();
}
dateParser.close();
if (calendar != null) {
return calendar.getTimeInMillis();
}
}
}
strVal = strVal.replaceAll(“,”, “”);这一步可以看出它把字符串的逗号全部去掉了。所以这并不是一个bug,而是有意地把逗号当作数字的分隔符处理了。
当然除了castToLong,castToInteger,castToFloat,castToDouble也都做了这样的处理,奇怪的是基础封装类中唯独Short没有这样做。而BigDecimal和BigInteger也没有这样做。
总之,有些时候,这样的处理方式并不是我们想要的的,这种时候只能自己处理了。