仿造 Gson 的自制 json 解析器
零 引子
0 原始碼
已上傳 github
https://github.com/mikylin-pr...
1 開發依賴
Maven : 3.3.9 (主要用作打包工具)
IDE : idea 2018.3
JDK : OpenJDK 11.0.1 (OracleJDK 8 以上即可)
2 寫在前頭
Litjson 是筆者讀了 Gson 原始碼之後的業餘之作,基本思路仿造了 Gson,但是功能上做了不少精簡,僅僅能適用於比較標準的 json 字串和 java 物件的互轉。
Litjson 在測試當中相容性表現良好,但是執行效率不如預期(不及 Gson),筆者一度想要放棄該專案,但是造輪子不易,既然造了就稍微聊一聊吧,歡迎探討進步。
一 自定義配置
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:
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,如果字串本身是一個列表的話會報錯 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); //第一個引數為要序列化的物件 //第二個引數是 readManager JWriter jWriter = new JWriter(object,writeManager); //只傳入物件 JWriter jWriter = 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 造輪子使我快樂