开源工程学习笔记之Fastjson(Part 1)

Part 1.反序列化部分还是从part0那个json串入手,看看Fastjson框架是怎么把他拆出来的。1.1 Fastjson中存取JSON对象的方法首先,Fastjson是用JSONObject和JSONArray这两个类分别描述json对象和json数组的。那么先把这两个类拆开来看看。1.1.1 JSONObject通过阅读json文档得知,一个object由若干个(可以是0个)键值对组成,
摘要由CSDN通过智能技术生成

Part 1.反序列化部分

还是从part0那个json串入手,看看Fastjson框架是怎么把他拆出来的。

1.1 Fastjson中存取JSON对象的方法

首先,Fastjson是用JSONObject和JSONArray这两个类分别描述json对象和json数组的。那么先把这两个类拆开来看看。

1.1.1 JSONObject

通过阅读json文档得知,一个object由若干个(可以是0个)键值对组成,其中键是字符串(string),值可以是string,number,object,array,boolean,null这几种情况。那么这种数据结构在Java中对应了什么呢?

没错就是Map啊!~~

所以JSONObject封装了一个private final Map<String, Object> map;,那么这个map是什么map呢?这取决于构造器了,默认的构造器是:

public JSONObject(){
    this(DEFAULT_INITIAL_CAPACITY, false);
}

第一个参数代表初始容量,程序设定为16,第二个参数代表是否有序,默认为false。

如果有序,则用LinkedHashMap实现,否则用HashMap实现。

既然这样,那么JSON对象的key就不可以是重复的~~之前拆的cJSON是可以重复的,个人感觉就不对了。因为json文档中说

An object is an unordered set of name/value pairs.

既然是set,就不能重复的吧。。。

这个类的方法都比较简单,大多是HashMap的封装,get和set这种的。首先是各种根据key取对象的方法,有取Object的,取Array的,取JavaBean的等等。

public JSONObject getJSONObject(String key) {
    Object value = map.get(key);

    if (value instanceof JSONObject) {
        return (JSONObject) value;
    }

    if (value instanceof String) {
        return JSON.parseObject((String) value);
    }

    return (JSONObject) toJSON(value);
}

取对象的逻辑很简单,就是如果他是对应的对象,则直接取出来,如果是字符串,则parse成对象,否则转换成JSONObject(如果是JavaBean)。

此外,该框架还支持直接取日期、取时间戳、取BigInteger等封装好的方法,在底层均是调用了com.alibaba.fastjson.util包里的工具方法,在此先不分析。

然后添加元素方面呢,有一个比较有意思的fluentPut:

public JSONObject fluentPut(String key, Object value) {
    map.put(key, value);
    return this;
}

因为他返回的是this,所以就可以在一行代码里连续加入多个元素:(记得以前看php的时候看到连续调用觉得特别方便,其实实现原理都是一样的。)

myObj.fluentPut("key1",value1).fluentPut("key2",value2);

1.1.2 JSONArray

JSONArray和JSONObject差不多,就是底层结构换成了ArrayList。

1.1.3 TypeUtils工具包中直接取特殊类型的方法

前面说过,这个框架支持将json中的value直接转换成各种数字类、高精度、日期、时间戳等数据结构,都是在TypeUtils包中的castToxxx方法实现的。

  • 基本类型

castToString、Byte、Char、Short、BigInteger、BigDecimal、Float、Double等都比较简单,主要就是特殊处理了value为”“,”NULL”,”null”三种情况,如果处理不了,就抛出JSONException异常。

  • Date

关键是Date,可见该框架支持了很多很多日期类型,首先调用了词法分析器JSONScanner,先检测是否符合ISO 8601标准,再检测是否是”yyyy-MM-dd HH:mm:ss”,”yyyy-MM-dd”,”yyyy-MM-dd HH:mm:ss.SSS”等形式。

else if (strVal.length() == 10) {
                    format = "yyyy-MM-dd";
                } else if (strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) {
                    format = "yyyy-MM-dd HH:mm:ss";
                }

顺便说下,这两句话风格统一下好不好。。。。

最后如果都不是,则看是不是时间戳,如果是时间戳则转换为对应的日期。
* JavaBean
还有一种特殊情况,就是取指定类,这个就比较麻烦了,如果是一些简单类如Integer,Float等直接调用相关方法即可,或者value存的就是你指定的类,都比较简单。

最复杂的情况就是,JSONObject里面存的是一个Map,而要取出的是这个Map对应的Bean。这个逻辑在方法castToJavaBean里实现。

1.2 输入字符串的反序列化

反序列化分为两部分,一是转换为JSON对象,二是转换为JavaBean。

1.2.1 String
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值