fastJson遇到的问题
概述
现在的代码开发中,json这种数据类型使用的是越来越多,因为它的存取速度都比较快,而且,使用起来非常的简单,今天工作的时候,我就遇到了一个关于json的生产问题,这个问题我之前确实还没有注意过,这边记录下。
问题再现
再一次远程调用获取相关信息成功之后,需要解析返回的json对象,这个json里面包含了三个元素,一个key为data的jsonObject,表示业务数据,一个Key为success的String,表示是否成功,一个key为resultMessage的失败原因。正常情况下,这个data是不可能为空的,但是今天不知道怎么了,远端返回的结果里面这个data就是空的,所以解析的时候就出现了如下异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject
at com.alibaba.fastjson.JSONObject.getJSONObject(JSONObject.java:109)
at com.example.demo.MainTest.main(MainTest.java:10)
当然这里要提前说明下,我这边使用的fastJson的版本是1.2.7,出现上面这个错是不是很奇怪,正常不应该返回一个null吗?怎么返回的是String类型不能转成JSONObject呢?
问题跟踪
问题到了这个地步还有什么好说的呢?只能模仿生产的返回,一步一步的去解析了。
public class MainTest {
public static void main(String[] args) {
// 写一个字符串,模拟生产的返回,其中data的值为空
String str = "{\"data\": \"\",\"success\": \"true\",\"resultMessage\": \"成功\"}";
// 序列化成json
JSONObject result = JSONObject.parseObject(str);
// 获取data的值
JSONObject data = result.getJSONObject("data");
System.out.println(data);
}
}
通过debug可以得知,第五行代码是可以正常执行的,返回如下:
{"data":"","success":"true","resultMessage":"成功"}
这个没有问题,那问题就在第6行代码上了,我们看一下getJSONObject方法:
public JSONObject getJSONObject(String key) {
Object value = map.get(key);
if (value instanceof JSONObject) {
return (JSONObject) value;
}
return (JSONObject) toJSON(value);
}
这边第2行代码根据key获取的value是"",这个显然不是JSONObject类型,直接走最后一行toJSON方法,
public static Object toJSON(Object javaObject, ParserConfig mapping) {
if (javaObject == null) {
return null;
}
if (javaObject instanceof JSON) {
return javaObject;
}
if (javaObject instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) javaObject;
JSONObject json = new JSONObject(map.size());
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
String jsonKey = TypeUtils.castToString(key);
Object jsonValue = toJSON(entry.getValue());
json.put(jsonKey, jsonValue);
}
return json;
}
if (javaObject instanceof Collection) {
Collection<Object> collection = (Collection<Object>) javaObject;
JSONArray array = new JSONArray(collection.size());
for (Object item : collection) {
Object jsonValue = toJSON(item);
array.add(jsonValue);
}
return array;
}
Class<?> clazz = javaObject.getClass();
if (clazz.isEnum()) {
return ((Enum<?>) javaObject).name();
}
if (clazz.isArray()) {
int len = Array.getLength(javaObject);
JSONArray array = new JSONArray(len);
for (int i = 0; i < len; ++i) {
Object item = Array.get(javaObject, i);
Object jsonValue = toJSON(item);
array.add(jsonValue);
}
return array;
}
if (mapping.isPrimitive(clazz)) {
return javaObject;
}
try {
List<FieldInfo> getters = TypeUtils.computeGetters(clazz, null);
JSONObject json = new JSONObject(getters.size());
for (FieldInfo field : getters) {
Object value = field.get(javaObject);
Object jsonValue = toJSON(value);
json.put(field.getName(), jsonValue);
}
return json;
} catch (IllegalAccessException e) {
throw new JSONException("toJSON error", e);
} catch (InvocationTargetException e) {
throw new JSONException("toJSON error", e);
}
}
这个方法有点长,但其实,真正执行了的也就是38行,获取value对应的class对象,这边返回的java.lang.String,再就是58到60行,判断这个对象是不是基础类型,是就直接返回,那么这边就返回的"",后面强制类型转换的时候当然就会报错。
上面这个问题似乎还不好解决啊,后来看了一下fastJson的几个高版本,已经解决了这个问题,我们来看一下1.2.51的getJSONObject方法:
public JSONObject getJSONObject(String key) {
Object value = map.get(key);
if (value instanceof JSONObject) {
return (JSONObject) value;
}
8 if (value instanceof String) {
9 return JSON.parseObject((String) value);
10 }
return (JSONObject) toJSON(value);
}
多了8-10行代码,针对String做了下处理,直接返回String解析之后的结果,这样就可以返回理想中的null了。
总结
平时代码开发过程中,一定要进行异常情况的测试,不能够想当然,要尽量覆盖每个分支,要让代码跑不崩溃。
fastJson遇到的问题的更多相关文章
- fastjson 混淆注意事项
使用fastjson 注意事项,主要表现: 1.加了符号Annotation 的实体类,一使用就会奔溃 2.当有泛型属性时,一使用就奔溃 在调试的时候不会报错,当你要打包签名混淆包的时候,就会出现上述 ...
- Java的Json解析包FastJson使用
阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parser. ...
- fastJson使用
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,由阿里巴巴的工程师开发. 主要特点: 快速FAST (比其它任何基于Java的解析器和生成器更快,包括jackson ...
- FASTJSON
package com.hanqi.test; import java.util.ArrayList;import java.util.Date;import java.util.List; impo ...
- Android总结之json解析(FastJson Gson 对比)
前言: 最近为了统一项目中使用的框架,发现项目中用到了两种json解析框架,他们就是当今非常主流的json解析框架:google的Gson 和阿里巴巴的FastJson,为了废除其中一个所以来个性能和 ...
- Android原生json和fastjson的简单使用
android原生操作json数据 主要是两个类 JSONObject 操作对象 JONSArray操作json数组 对象转json //创建学生对象 Student student=new ...
- FastJson的简单实用
一.FastJson的理解 在工作中,经常客服端需要和服务端进行通信,目前很多项目都采用JSON的方式进行数据传输,简单的参数可以通过手动拼接JSON字符串,但如果请求的参数过多,采用手动拼接JSON ...
- Android JSON、GSON、FastJson的封装与解析
声明: 1.本帖只提供代码,不深入讲解原理.如果读者想要深入了解,那就不要在这个帖子上浪费时间了 2.客户端用的是Google官方的Volley访问服务器,具体了解Volley请戳 这里 3.本帖三种 ...
- java分享第十三天(fastjson生成和解析json数据,序列化和反序列化数据)
fastjson简介:Fastjson是一个Java语言编写的高性能功能完善的JSON库.fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jack ...
- FastJson和AsyncHttpCLient
Android的展示数据,除了上章所讲的本地存储外,大部分数据都来自于网络.首先介绍一下Android APP开发常见的网络操作方式.从网络层面上有底层的tcp/ip,也就是我们常见的socket套接 ...
随机推荐
- Python模块 3
time模块 在计算中时间共有三种方式: 1.时间戳: 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行“type(time.time())”,返回的是flo ...
- python 之生成器的介绍
# 用生成器(generators)方便地写惰性运算 def double_numbers(iterable): for i in iterable: yield i + i # 生成器只有在需要时才 ...
- Discuz3.2与Java 项目整合单点登陆
JAVA WEB项目与Discuz 论坛整合的详细步骤完全版目前未有看到,最近遇到有人在问,想到这个整个不是一时半会也解释不清楚.便把整个整合过程以及后续碰到的问题解决方案写下,以供参考. 原理 Di ...
- Redhat终端中文乱码解决
文件中的中文以及命令反馈的中文能够正常显示,但是在终端中用ls等命令查看文件时会出现乱码. 我在i18n文件中加了下面两行内容(本来只有第一行),后来就能正常显示了.
- 2.1 maven配置多镜像地址
背景: 自己在平时写项目用的是阿里的镜像地址,而在开发公司的项目是用的是公司提供的镜像地址,这就导致了每次使用的时候 都需要来回的修改maven的settings.xml文件,这样很容易出错,而且还浪 ...
- CSS之实现垂直时间线展示相关内容效果
如下,最近在工作中遇到实现时间线效果的需求,用纯css即可实现,下面给出详细实现代码. html: <div class="time_line_list_wrap hide" ...
- 第 10 章 容器监控 - 079 - 监控利器 sysdig
sysdig 是一个轻量级的系统监控工具,同时它还原生支持容器. 通过 sysdig 我们可以近距离观察 linux 操作系统和容器的行为. Linux 上有很多常用的监控工具,比如 strace,t ...
- Axure 矩形交互样式与单选按钮组设置
矩形交互样式: 场景:当点击昵称的时候,密码栏会显示红框,当点击密码的时候,昵称会显示红框 补充:昵称栏和密码栏的组成其实是一个矩形框和一个文本框,这样才可以设置出场景所示的样式 这里的设置只是简单的 ...
- IPFS 使用入门
在上一篇文章介绍了IPFS要做什么, 本篇文章介绍下IPFS怎么用, 按照本站的风格,我不会仅仅把一个个命令列出来,同时会说明命令在后面为我们做了什么. IPFS 安装 要使用IPFS, 第一步肯定是 ...
- CHM文件命令转换成html
在Windows下chm转换为html的超简单方法(反编译CHM文件的方法) 通过调用Windows命令,将chm 文件转换为html 文件. 方法: 命令行(cmd),输入hh -decompile ...