Snack3 一個新的微型JSON框架


Snack3 一個新的微型JSON框架

一個作品,一般表達作者的一個想法。因為大家想法不同,所有作品會有區別。就做技術而言,因為有很多有區別的框架,所以大家可以選擇的框架很豐富。

snack3。基於jdk860kb,無其它依賴,非常小巧。

  • 強調文檔樹的鏈式操控和構建能力
  • 強調中間媒體,方便不同格式互轉
  • 支持序列化、反序列化
  • 支持Json path查詢

ONode 即 One node 之意;借簽了 Javascript 所有變量由 var 申明,及 Xml dom 一切都是 Node 的設計。這應該也是與別的框架不同之處。

設計思路

  • ONode是一個接口界面,內部由nodeTypenodeData組成。通過nodeType進行類型識別,通過nodeData容納所有的類型數據。

  • 采用Fromer->ONode->Toer的架構設計。這是重要的一個設計,可使轉換具有很強的擴展能力,FromerToer 各做一半工作,也可各自切換(有好處也會有壞處)。

  • 強調非null操作,通過o.isNull()進行判斷(留意后面-get(key | idx)接口的注釋;可通過getOrNull(key | idx) 獲取 null

項目源碼

Meven配置

<dependency>
  <groupId>org.noear</groupId>
  <artifactId>snack3</artifactId>
  <version>3.1.8</version>
</dependency>

一、簡單的代碼演示

  • 簡單操控
//1.加載json
// name支持沒有引號
// 字符串支持單引號(在java里寫代碼方便點;輸出是標准的引號)
ONode n = ONode.load("{code:1,msg:'Hello world',data:{list:[1,2,3,4,5]}}");

//2.1.取一個屬性的值
String msg = n.get("msg").getString();

//2.2.取列表里的一項
int li2  = n.get("data").get("list").get(2).getInt();
int li2  = n.select("data.list[2]").getInt(); //使用josn path 

//2.3.獲取一個數組
List<Integer> ary = n.get("data").get("list").toObject(ArrayList.class);
List<Integer> ary = n.select("data.list").toObject(ArrayList.class); //使用josn path 

//3.1.設置值
n.set("msg","Hello world2");
n.get("msg").val("Hello world2"); //另一種設置方式

//3.2.設置列表里的一項值為12
n.get("data").get("list").get(2).val(12);
n.select("data.list[2]").val(12); //使用josn path 

//3.3.清掉一個數組
n.get("data").get("list").clear();
n.select("data.list").clear(); //使用josn path 

二、更多代碼演示

  • 1.字符串化
//將 java object 轉為 json
String json = ONode.stringify(user);
  • 2.序列化
//1.序列化(通過@type申明類型)
String json = ONode.serialize(user);

//2.反序列化
UserModel user = ONode.deserialize(json, UserModel.class);
  • 3.轉換
//1.1.將json string 轉為 ONode
ONode o = ONode.load(json); 

//1.2.將java bean 轉為 ONode
ONode o = ONode.load(user); 

//2.1.將 ONode 轉為 string(由轉換器決定,默認轉換器為json)
o.toString();

//2.2.將 ONode 轉為 json
o.toJson();

//2.3.將 ONode 轉為XxxModel (例:UserModel)
o.toObject(UserModel.class);

//>將 ONode 轉為 Map 或 List 或 常規值
o.toObject(null);

//>將 ONode 轉為 自動類型的 Java Object
o.toObject(Object.class);

  • 4.填充
ONode o = ONode.load("{code:1,msg:'Hello world!'}");

//填充java object
List<UserModel> list = new ArrayList<>();
//...
o.get("data").get("list").fill(list);

//填充string json
o.get("data").get("list").fill("[{a:1,b:2},{a:2,c:3}]");
  • 5.一個應用示例(極光推送的rest api調用)
public static void push(Collection<String> alias_ary, String text)  {
    ONode data = new ONode().build((d)->{
        d.get("platform").val("all");

        d.get("audience").get("alias").addAll(alias_ary);

        d.get("options")
                .set("apns_production",false);

        d.get("notification").build(n->{
            n.get("ios")
                    .set("alert",text)
                    .set("badge",0)
                    .set("sound","happy");
        });
    });

    String message = data.toJson();
    String author = Base64Util.encode(appKey+":"+masterSecret);

    Map<String,String> headers = new HashMap<>();
    headers.put("Content-Type","application/json");
    headers.put("Authorization","Basic "+author);

    HttpUtil.postString(apiUrl, message, headers);
}
  • 5.數據遍歷
//遍歷Object數據 方案1
o.forEach((k,v)->{
  //...
});
//遍歷Object數據 方案2
for(Map.Entry<String,ONode> kv : n.obj().entrySet()){
  //...    
}

//遍歷Array數據 方案1
o.forEach((v)->{
  //...
});
//遍歷Array數據 方案2
for(ONode v : o.ary()){
  //..
}

三、混合加載與轉換代碼演示

List<UserModel> list = new ArrayList<>();
//..
ONode o = ONode.load("{code:1,msg:'succeed'}");
o.get("data").get("list").fill(list);

關於三組類型接口的設計(Json object,array,value)

  • 關於json object的操作
-obj() -> Map<String,ONode>             //獲取節點對象數據結構體(如果不是對象類型,會自動轉換)
-contains(key:String) -> bool           //是否存在對象子節點?
-get(key:String) -> child:ONode         //獲取對象子節點(不存在,生成新的子節點並返回)
-getOrNull(key:String) -> child:ONode   //獲取對象子節點(不存在,返回null)
-getNew(key:String) -> child:ONode      //生成新的對象子節點,會清除之前的數據
-set(key:String,val:Object) -> self:ONode           //設置對象的子節點(會自動處理類型)//val:為常規類型或ONode
-setNode(key:String,val:ONode) -> self:ONode        //設置對象的子節點,值為ONode類型
-setAll(obj:ONode) -> self:ONode                    //設置對象的子節點,將obj的子節點搬過來
-setAll(map:Map<String,T>) ->self:ONode             //設置對象的子節點,將map的成員搬過來
-setAll(map:Map<String,T>, (n,t)->..) ->self:ONode  //設置對象的子節點,將map的成員搬過來,並交由代理處置
-remove(key:String)     //移除對象的子節點
-forEach((k,v)->..)     //遍歷對象的子節點
  • 關於json array的操作
-ary() -> List<ONode>                   //獲取節點數組數據結構體(如果不是數組,會自動轉換)
-get(index:int)  -> child:ONode                 //獲取數組子節點(超界,返回空節點)
-getOrNull(index:int)  -> child:ONode           //獲取數組子節點(超界,返回null)
-addNew() -> child:ONode                        //生成新的數組子節點
-add(val) -> self:ONode                         //添加數組子節點 //val:為常規類型或ONode
-addNode(val:ONode) -> self:ONode               //添加數組子節點,值為ONode類型
-addAll(ary:ONode)  -> self:ONode               //添加數組子節點,將ary的子節點搬過來
-addAll(ary:Collection<T>) -> self:ONode                //添加數組子節點,將ary的成員點搬過來
-addAll(ary:Collection<T>,(n,t)->..) -> self:ONode      //添加數組子節點,將ary的成員點搬過來,並交由代理處置
-removeAt(index:int)    //移除數組的子節點
-forEach(v->..)         //遍歷數組的子節點
  • 關於json value的操作
-val() -> OValue                //獲取節點值數據結構體(如果不是值類型,會自動轉換)
-val(val:Object) -> self:ONode  //設置節點值 //val:為常規類型或ONode
-getString()    //獲取值並以string輸出 //如果節點為對象或數組,則輸出json
-getShort()     //獲取值並以short輸出...(以下同...)
-getInt()
-getBoolean()
-getLong()
-getDate()
-getFloat()
-getDouble()
-getDouble(scale:int)
-getChar()

關於序列化的特點

  • 對象
{"@type":"...","a":1,"b":"2"}
  • 數組(可以精准反序列化列表類型;需要特性開啟)
[{"@type":"..."},[1,2,3]]  

關於Json path的支持

  • 支持完整的Json path的選擇操作
支持操作 說明
$ 查詢根元素(或當前元素)。
這將啟動所有路徑表達式(可以不輸)。
* 通配符,必要時可用任何地方的名稱或數字。
.. 深層掃描。 必要時在任何地方可以使用名稱。
. 點,表示子節點
[' ' (, ' ')] 括號表示子項
[ (, )] 數組索引或索引
[start:end] 數組切片操作

例:n.select("$.store.book[0].title")n.select("$['store']['book'][0]['title']")

附:完整的接口字典

//初始化操作
//
-asObject() -> self:ONode  //將節點切換為對象
-asArray()  -> self:ONode  //將節點切換為數組
-asValue()  -> self:ONode  //將節點切換為值
-asNull()   -> self:ONode  //將節點切換為null

//檢測操作
//
-isObject() -> bool  //檢查節點是否為對象
-isArray()  -> bool  //檢查節點是否為數組
-isValue()  -> bool  //檢查節點是否為值
-isNull()   -> bool  //檢查節點是否為null

//公共
//
-nodeData() -> ONodeData //獲取節點數據
-nodeType() -> ONodeType //獲取節點類型

-cfg(cfg:Constants) -> self:ONode   //切換配置
-cfg() -> Constants 				//獲取配置

-build(n->..) -> self:ONode     	//節點構建表達式
-select(jpath:String) -> new:ONode 	                    //使用JsonPath表達式選擇節點(默認緩存路徑編譯)
-select(jpath:String, useStandard:boolean)-> new:ONode  //useStandard:使用標准模式,默認非標准
-select(jpath:String, useStandard:boolean, cacheJpath:boolean)-> new:ONode   //cacheJpath:是否緩存javaPath編譯成果,默認緩存

-clear()        //清除子節點,對象或數組有效
-count() -> int //子節點數量,對象或數組有效


//值操作
//
-val() -> OValue                //獲取節點值數據結構體(如果不是值類型,會自動轉換)
-val(val:Object) -> self:ONode  //設置節點值 //val:為常規類型或ONode
-getString()    //獲取值並以string輸出 //如果節點為對象或數組,則輸出json
-getShort()     //獲取值並以short輸出...(以下同...)
-getInt()
-getBoolean()
-getLong()
-getDate()
-getFloat()
-getDouble()
-getDouble(scale:int)
-getChar()

//對象操作
//
-obj() -> Map<String,ONode>                     //獲取節點對象數據結構體(如果不是對象類型,會自動轉換)
-readonly() -> self:ONode                       //只讀形態(get時,不添加子節點)
-contains(key:String) -> bool                   //是否存在對象子節點?
-rename(key:String,newKey:String) -> self:ONode //重命名子節點並返回自己
-get(key:String) -> child:ONode                 //獲取對象子節點(不存在,生成新的子節點並返回)
-getOrNull(key:String) -> child:ONode           //獲取對象子節點(不存在,返回null)
-getNew(key:String) -> child:ONode              //生成新的對象子節點,會清除之前的數據
-set(key:String,val:Object) -> self:ONode           //設置對象的子節點(會自動處理類型)
-setNode(key:String,val:ONode) -> self:ONode        //設置對象的子節點,值為ONode類型
-setAll(obj:ONode) -> self:ONode                    //設置對象的子節點,將obj的子節點搬過來
-setAll(map:Map<String,T>) ->self:ONode             //設置對象的子節點,將map的成員搬過來
-setAll(map:Map<String,T>, (n,t)->..) ->self:ONode  //設置對象的子節點,將map的成員搬過來,並交由代理處置
-remove(key:String)                   //移除對象的子節點
-forEach((k,v)->..) -> self:ONode     //遍歷對象的子節點

//數組操作
//
-ary() -> List<ONode>                   //獲取節點數組數據結構體(如果不是數組,會自動轉換)
-get(index:int)  -> child:ONode                 //獲取數組子節點(超界,返回空節點)
-getOrNull(index:int)  -> child:ONode           //獲取數組子節點(超界,返回null)
-addNew() -> child:ONode                        //生成新的數組子節點
-add(val) -> self:ONode                         //添加數組子節點 //val:為常規類型或ONode
-addNode(val:ONode) -> self:ONode               //添加數組子節點,值為ONode類型
-addAll(ary:ONode)  -> self:ONode               //添加數組子節點,將ary的子節點搬過來
-addAll(ary:Collection<T>) -> self:ONode                //添加數組子節點,將ary的成員點搬過來
-addAll(ary:Collection<T>,(n,t)->..) -> self:ONode      //添加數組子節點,將ary的成員點搬過來,並交由代理處置
-removeAt(index:int)                 //移除數組的子節點
-forEach(v->..) -> self:ONode        //遍歷數組的子節點

//特性操作(不破壞數據的情況上,添加數據;或用於構建xml dom)
//
-attrGet(key:String) -> String                  //獲取特性
-attrSet(key:String,val:String) -> self:ONode   //設置特性
-attrForeach((k,v)->..) -> self:ONode           //遍歷特性

//轉換操作
//
-toString() -> String           //轉為string (由字符串轉換器決定,默認為json)
-toJson() -> String             //轉為json string
-toData() -> Object 			//轉為數據結構體(Map,List,Value)
-toObject(clz:Class<T>) -> T    //轉為java object(clz=Object.class:自動輸出類型)

-to(toer:Toer, clz:Class<T>) -> T   //將當前節點通過toer進行轉換
-to(toer:Toer) -> T                 //將當前節點通過toer進行轉換

//填充操作(為當前節點填充數據;source 為 String 或 java object)
-fill(source:Object)    -> self:ONode               //填充數據
-fill(source:Object, fromer:Fromer) -> self:ONode   //填充數據,由fromer決定處理

/**
 * 以下為靜態操作
**/

//加載操作(source 為 String 或 java object)
//
+load(source:Object) -> new:ONode    //加載數據
+load(source:Object, cfg:Constants) -> new:ONode
+load(source:Object, cfg:Constants, fromer:Fromer) -> new:ONode

//加載 string
+loadStr(source:String) -> new:ONode	//僅String
//加載 java object
+loadObj(source:Object) -> new:ONode	//僅java object

//字符串化操作
//
+stringify(source:Object) -> String                   //字符串化;

//序列化操作
//
+serialize(source:Object) -> String                   //序列化(帶@type屬性)
+deserialize(source:String) -> T                      //反序列化
+deserialize(source:String, clz:Class<?>) -> T        //反序列化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM