700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject 的解决办法

ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject 的解决办法

时间:2024-02-10 10:38:58

相关推荐

ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject 的解决办法

问题概述

关于这个问题,是与第三方公司合作,远程调用服务接口时(就相当于调用远程服务提供者)遇到的这个问题,“java.lang.ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject” 表示不能将JSON字符串转换为JSONObject对象。

部分异常截图如下:

具体信息如下:

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObjectat com.alibaba.fastjson.JSON.parseObject(JSON.java:229)... 56 more

解决办法

当调用接口接收到信息后,使用的是alibaba的FastJson工具类来进行反序列化的,示例代码如下:

@Testpublic void fastjson() {// 将员工对象序列化为Json字符串String jsonString = JSON.toJSONString(initEmployee());System.out.println(jsonString);// 将Json字符串反序列化为Java对象Employee employee = JSON.parseObject(jsonString, Employee.class);System.out.println("empName: " + employee.getName());}

或者Jackson(相对于FastJson,FastJson在支持泛型方面更好些),示例代码如下:

@Testpublic void jackson() throws Exception {ObjectMapper objectMapper = new ObjectMapper();// 将Java对象序列化为Json字符串String asString = objectMapper.writeValueAsString(initEmployee());System.out.println(asString);// 将Json字符串反序列化为Java对象Employee employee = objectMapper.readValue(asString, Employee.class);System.out.println("empName: " + employee.getName());}

当然你也可以使用Google的Gson,示例代码如下:

@Testpublic void gson() {Gson gson = new GsonBuilder().create();// 将Java对象序列化为Json字符串String json = gson.toJson(initEmployee());System.out.println(json);// 将Json字符串反序列化为Java对象Employee employee = gson.fromJson(json, Employee.class);System.out.println("empName: " + employee.getName());}

问题排查:

查看调用返回的结果,发现了惊奇的一幕,在返回的调用结果里面出现了很多的转义字符,不是一个正确的JSON字符串,当然不能序列化成功了,示例内容如下:

"{\"id\":\"1001\",\"name\":\"张三\",\"password\":\"zhangsan\"}"

(当然以上只是为了证明问题的测试数据,实际数据接口数据要比这个复杂的多,而且进行了特殊的加密算法,但返回的数据格式与上相同,且最终的解决办法相同)

解决办法:

1、通过手动剔除转义字符的方式,示例代码如下:

@Testpublic void tData() {String data01 = "{\"id\":\"1001\",\"name\":\"张三\",\"password\":\"zhangsan\"}";System.out.println("data01:" + data01);// 序列化为JSON字符串String data02 = JSON.toJSONString(data01);System.out.println("data02:" + data02);//通过 replace 去掉斜杠String data03 = data02.replace("\\", "");System.out.println("data03:" + data03);//去掉首尾的引号String data04 = data03.substring(1, data03.length() - 1);System.out.println("data04:" + data04);Map map = JSON.parseObject(data04, Map.class);System.out.println(map.get("name"));}

得到了想要的结果如下:

但是上面这个有个问题,每一次的转换都会去遍历所有的内容,当内容长度小时无所谓,但是当长度较长时,问题就来了,会消耗大量的时间,例如,博主本人的数据量较大,没调用一次接口都会花费一到两分钟来处理结果,这个。。。

性能优化:通过Apache的commons-lang工具包中有很多字符串处理的工具类,StringEscapeUtils就是其中之一,不过需要注意的是StringEscapeUtils是2.3版本以上才加上的,不过博主在官网看到3.0以后又开始弃用了并将该功能搬移到了commons-text工具包中,所以需要注意导入对应的包才行呀!!!

如果使用commons-lang则添加依赖:

<dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency>

如果使用commons-text则添加依赖:

<dependency><groupId>mons</groupId><artifactId>commons-text</artifactId><version>1.6</version></dependency>

使用StringEscapeUtils工具类进行反序列化转义字符,示例内容如下:

@Testpublic void tData() {String data01 = "{\"id\":\"1001\",\"name\":\"张三\",\"password\":\"zhangsan\"}";System.out.println("data01:" + data01);// 序列化为JSON字符串String data02 = JSON.toJSONString(data01);System.out.println("data02:" + data02);// 通过StringEscapeUtils工具类反序列化转义字符String data04 = StringEscapeUtils.unescapeJava(data01);System.out.println("data04:" + data04);Map map = JSON.parseObject(data04, Map.class);System.out.println(map.get("name"));}

使用起来,结果一样,但是在处理大的较长的字符串内容时,使用StringEscapeUtils的效果会更佳的显著咯!!!

当然StringEscapeUtils还有很多好玩而且非常使用的方法,这个就需要自己去玩了,如下图:

好了,关于ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject 的解决办法 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。

歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。