本来今天,开开心心的在撸代码,结果被一个fastJson的坑坑了一个多小时,整个人都不好了。为了防止有同学重蹈我的覆辙,将这个问题做一下记录。希望可以帮到各位小伙伴。
需求如下:我有一个map形式的json字符串,key为字符串,value也为字符串(json格式),我现在要取所有的value,并将期转换为对应的对象形式。
代码如下(因为是项目中的问题,当时问题点并没有这么容易看出,为了简单易懂写了一个测试,只是为了将这个问题暴露出来)
代码1
@Test
public void fastJsonTest2() {
//模拟json
String json = "{\"时尚零售\":{\"trade\":\"时尚零售\",\"passengerflow\":\"126.00\",\"sale\":\"67800.00\"},\"非遗\":{\"trade\":\"非遗\",\"passengerflow\":\"123.00\",\"sale\":\"34578.00\"},\"客栈\":{\"trade\":\"客栈\",\"passengerflow\":\"1235.00\",\"sale\":\"34000.00\"},\"民俗\":{\"trade\":\"民俗\",\"passengerflow\":\"5678.00\",\"sale\":\"12000.00\"},\"特色餐饮\":{\"trade\":\"特色餐饮\",\"passengerflow\":\"8900.00\",\"sale\":\"9009.00\"}}";
//将字符串转换为map形式
Map map = JSON.parseObject(json, Map.class);
//创建一个list存放对应的value对象
List saleList = new ArrayList<>();
// 使用java8进行循环遍历
map.forEach((s1, s2) -> {
//将s2json字符串转换为对象
Sale sale = JSON.parseObject(s2, Sale.class);
//存入到list集合中
saleList.add(sale);
});
//输出所有
System.out.println(saleList);
}
开开心心的运行了代码,心想自己太机智了。还用了java8新特性。结果如下
说好的循环遍历list所有的值呢?怎么回事? 哪里出了问题?
代码2
@Test
public void fastJsonTest2() {
//模拟json
String json = "{\"时尚零售\":{\"trade\":\"时尚零售\",\"passengerflow\":\"126.00\",\"sale\":\"67800.00\"},\"非遗\":{\"trade\":\"非遗\",\"passengerflow\":\"123.00\",\"sale\":\"34578.00\"},\"客栈\":{\"trade\":\"客栈\",\"passengerflow\":\"1235.00\",\"sale\":\"34000.00\"},\"民俗\":{\"trade\":\"民俗\",\"passengerflow\":\"5678.00\",\"sale\":\"12000.00\"},\"特色餐饮\":{\"trade\":\"特色餐饮\",\"passengerflow\":\"8900.00\",\"sale\":\"9009.00\"}}";
//将字符串转换为map形式
Map map = JSON.parseObject(json, Map.class);
//创建一个list存放对应的value对象
List saleList = new ArrayList<>();
// 使用java8进行循环遍历
map.forEach((s1, s2) -> {
//将s2json字符串转换为对象
Sale sale = JSON.parseObject(s2.toString(), Sale.class);
//存入到list集合中
saleList.add(sale);
});
//输出所有
System.out.println(saleList);
}
仔细对比两个代码。区别就在于map的泛型以及s2的toString。具体原理如下
代码3
@Test
public void fastJsonTest() throws Exception {
String json = "{\"时尚零售\":{\"trade\":\"时尚零售\",\"passengerflow\":\"126.00\",\"sale\":\"67800.00\"},\"非遗\":{\"trade\":\"非遗\",\"passengerflow\":\"123.00\",\"sale\":\"34578.00\"},\"客栈\":{\"trade\":\"客栈\",\"passengerflow\":\"1235.00\",\"sale\":\"34000.00\"},\"民俗\":{\"trade\":\"民俗\",\"passengerflow\":\"5678.00\",\"sale\":\"12000.00\"},\"特色餐饮\":{\"trade\":\"特色餐饮\",\"passengerflow\":\"8900.00\",\"sale\":\"9009.00\"}}";
//客流销售信息
Map saleMap = JSON.parseObject(json, Map.class);
System.out.println(saleMap);
System.out.println(saleMap.get("特色餐饮").getClass()); //class com.alibaba.fastjson.JSONObject
String s1 = saleMap.get("特色餐饮").toString(); //正常
String s2 = saleMap.get("特色餐饮")+""; //正常
String s3 = String.valueOf(saleMap.get("特色餐饮")); //正常
//String s4 = (String) saleMap.get("特色餐饮"); //报错 类型转换异常
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
原来是因为转换成map后key确实是String,但是value居然是JsonObject,从而当我们给Map添加了双String泛型的时候相当于将JsonObject强转成了String,然后造成的报错。所以我们使用s1,s2,s3这三种方式将其转换为String类型。之后再进行操作即可。
虽然这个问题看似并没有什么难度。但是当你并不知道是哪里造成的问题时,而且还是在项目中的时候还是比较蛋疼的。
个人感觉这是fastJson的一个坑。。。希望可以帮助到更多的小伙伴。
以上结论仅为本人个人理解,如有问题,望指出,共同成长