仿造 Gson 的自制 json 解析器

零 引子

0 源碼

已上傳 github: https://github.com/mikylin-pr...java

1 開發依賴

Maven : 3.3.9 (主要用做打包工具)
IDE : idea 2018.3
JDK : OpenJDK 11.0.1 (OracleJDK 8 以上便可)git

2 寫在前頭

Litjson 是筆者讀了 Gson 源碼以後的業餘之做,基本思路仿造了 Gson,可是功能上作了很多精簡,僅僅能適用於比較標準的 json 字符串和 java 對象的互轉。github

Litjson 在測試當中兼容性表現良好,可是執行效率不如預期(不及 Gson),筆者一度想要放棄該項目,可是造輪子不易,既然造了就稍微聊一聊吧,歡迎探討進步。json

一 自定義配置

Litjson 可使用組件 OptionBox 進行各類參數的修改,OptionBox 由其靜態內部類 OptionBoxBuildr 建立:安全

//建立一個 builder
OptionBox.OptionBoxBuilder boxBuilder = OptionBox.OptionBoxBuilder.builder();

//使用 builder 建立 OptionBox
OptionBox box = boxBuilder
        //在 json 字符串反序列化過程當中要忽略的字符
        //默認會忽略空字符串和換行符等字符類型
        .addIgnoreChar('c')
        //傳入一個 List<Character>,批量設置忽略字符
        .addIgnoreChars(chars)
        //在 json 字符串反序列化過程當中須要識別的日期格式,默認僅有一種 yyyy-MM-dd HH:mm:ss
        .addReadDateFormat("yyyy-mm-dd")
        //傳入一個 List<DateFormat>,批量設置識別的日期格式
        .addReadDateFormats(dateformats)
        //TypeHandler 爲類型轉換器
        //使用者能夠自定義須要使用的類型轉換器,並以 map 的格式傳入
        //默認只有 Integer/Long/String/Double/Float/Date 這幾種類型
        .addTypeHandlers(handlerMap)
        //在將 java bean 序列化的過程當中使用單引號仍是雙引號
        //true 爲雙引號,false 爲單引號,不設置的時候默認爲 true
        .isQoubleQuotationMarks(true)
        //在將 java bean 序列化的過程當中須要轉的日期格式
        //默認爲 yyyy-MM-dd HH:mm:ss
        .writeDateFormat(dateformat)
        //建立 OptionBox
        .over();

OptionBox 的功能目前較少,後期補充。併發

TypeHandler 是一個 Listjson 中的接口,使用者能夠自行實現該接口用以解析須要的類型,做用相似 Gson 中的 TypeAdapter:ide

public interface TypeHandler<T> {
    T read(String value);
    String write(T t);
}

!!!自定義 TypeHandler 的功能僅爲預留,暫未作支持。高併發

二 反序列化

JReader 是 Litjson 中用於讀取 json 字符串(反序列化)的組件,提供多種構造器進行建立:工具

//配置盒
OptionBox box = OptionBox.OptionBoxBuilder.builder().over();
//JReader 的輔助工具類,使用配置盒進行建立
ReadManager readManager = new ReadManager(box);

//第一個參數爲 json 字符串
//第二個參數是須要讀成的 java class 類型
//第三個參數表示 是否爲列表,true 表明是列表,false 表明是 object
//若是第三個參數爲 true,則 classType 會表示成列表內的泛型類型
//第四個參數是 readManager
JReader jReader = new JReader(jsonString,classType,true,readManager);
//只傳入 json 字符串,會輸出一個 map,若是字符串自己是一個列表的話會報錯
//不傳入 readManager,配置均使用默認
JReader jReader1 = new JReader(jsonString);
//同上,只是會輸出成一個 java class 類型
JReader jReader2 = new JReader(jsonString,classType);
//輸出成一個列表
JReader jReader3 = new JReader(jsonString,classType,true);

//輸出對象,參數設置必須爲輸出非列表
Object o = jReader.toObj();
//輸出列表對象,參數設置必須爲輸出列表
List list = jReader.toArray();

三 序列化

JWriter 是 Litjson 中用於輸出 json 字符串(序列化)的組件,提供多種構造器進行建立:測試

//配置盒
OptionBox box = OptionBox.OptionBoxBuilder.builder().over();
//JWriter 的輔助工具類,使用配置盒進行建立
WriteManager writeManager = new WriteManager(box);

//第一個參數爲要序列化的對象
//第二個參數是 writeManager
JWriter jWriter = new JWriter(object,writeManager);
//只傳入對象,不傳入 writeManager,配置均使用默認
JWriter jWriter1 = new JWriter(object);

//輸出 json 字符串
String json = jWriter.toJson();

四 門面

介於通常情景下快速開發的需求,筆者參考了 Fastjson 的使用以後給 JReader 和 JWriter 整合了一個靜態門面類供使用者更加方便的調用:

//json 字符串的反序列化過程
Object obj = JSONBootstrap.read(jsonString);
//加入指定類型的反序列化
T obj = JSONBootstrap.read(jsonString,class<T>);
//java bean 序列化過程
String json = JSONBootstrap.write(obj);

五 一點嘮叨

0 截止到 version 0.0.1,使用 IDEA 的 Statistic 插件統計共計約 2400 行 java 代碼

1 Litjson 的使用須要使用到 java bean 的無參構造器和參數的 get/set 方法,沒有的話在反射建立階段就會報錯

2 現階段支持的類型還不多,只能支持 java bean/Map/Collection/Integer/Long/Float/Double/String/Date

3 高併發下的 DateFormat 存在線程安全問題

4 筆者對項目總體性把握的功力還太淺,體如今對象封裝、錯誤管理等各方面,有待後期完善

5 春節假期的自 high 做品,隨緣維護,謹慎用於生產環境

6 造輪子使我快樂
相關文章
相關標籤/搜索