Snack3 一個(gè)微型JSON框架
一個(gè)作品洛史,一般表達(dá)作者的一個(gè)想法。因?yàn)榇蠹蚁敕ú煌戳撸凶髌窌?huì)有區(qū)別也殖。就做技術(shù)而言,因?yàn)橛泻芏嘤袇^(qū)別的框架务热,所以大家可以選擇的框架很豐富毕源。
snack3∩孪埃基于jdk8
霎褐,60kb
,無(wú)其它依賴(lài)该镣,非常小巧冻璃。
- 強(qiáng)調(diào)文檔樹(shù)的鏈?zhǔn)讲倏睾蜆?gòu)建能力
- 強(qiáng)調(diào)中間媒體,方便不同格式互轉(zhuǎn)
- 支持
序列化损合、反序列化
- 支持
Json path
查詢(xún)
ONode 即 One node
之意省艳;借簽了 Javascript
所有變量由 var
申明,及 Xml dom
一切都是 Node
的設(shè)計(jì)嫁审。這應(yīng)該也是與別的框架不同之處跋炕。
設(shè)計(jì)思路
ONode
是一個(gè)接口界面,內(nèi)部由nodeType
和nodeData
組成律适。通過(guò)nodeType
進(jìn)行類(lèi)型識(shí)別辐烂,通過(guò)nodeData
容納所有的類(lèi)型數(shù)據(jù)遏插。采用
Fromer
->ONode
->Toer
的架構(gòu)設(shè)計(jì)。這是重要的一個(gè)設(shè)計(jì)纠修,可使轉(zhuǎn)換具有很強(qiáng)的擴(kuò)展能力胳嘲,Fromer
和Toer
各做一半工作,也可各自切換(有好處也會(huì)有壞處)扣草。強(qiáng)調(diào)非null操作了牛,通過(guò)o.isNull()進(jìn)行判斷(留意后面
-get(key | idx)
接口的注釋?zhuān)豢赏ㄟ^(guò)getOrNull(key | idx)
獲取null
)
項(xiàng)目源碼
Meven配置
<dependency>
<groupId>org.noear</groupId>
<artifactId>snack3</artifactId>
<version>3.1.5.12</version>
</dependency>
一、簡(jiǎn)單的代碼演示
- 簡(jiǎn)單操控
//1.加載json
// name支持沒(méi)有引號(hào)
// 字符串支持單引號(hào)(在java里寫(xiě)代碼方便點(diǎn)辰妙;輸出是標(biāo)準(zhǔn)的引號(hào))
ONode n = ONode.load("{code:1,msg:'Hello world',data:{list:[1,2,3,4,5]}}");
//2.1.取一個(gè)屬性的值
String msg = n.get("msg").getString();
//2.2.取列表里的一項(xiàng)
int li2 = n.get("data").get("list").get(2).getInt();
int li2 = n.select("data.list[2]").getInt(); //使用josn path
//2.3.獲取一個(gè)數(shù)組
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.設(shè)置值
n.set("msg","Hello world2");
n.get("msg").val("Hello world2"); //另一種設(shè)置方式
//3.2.設(shè)置列表里的一項(xiàng)值為12
n.get("data").get("list").get(2).val(12);
n.select("data.list[2]").val(12); //使用josn path
//3.3.清掉一個(gè)數(shù)組
n.get("data").get("list").clear();
n.select("data.list").clear(); //使用josn path
二鹰祸、更多代碼演示
- 1.字符串化
//將 java object 轉(zhuǎn)為 json
String json = ONode.stringify(user);
- 2.序列化
//1.序列化(通過(guò)@type申明類(lèi)型)
String json = ONode.serialize(user);
//2.反序列化
UserModel user = ONode.deserialize(json, UserModel.class);
- 3.轉(zhuǎn)換
//1.1.將json string 轉(zhuǎn)為 ONode
ONode o = ONode.load(json);
//1.2.將java bean 轉(zhuǎn)為 ONode
ONode o = ONode.load(user);
//2.1.將 ONode 轉(zhuǎn)為 string(由轉(zhuǎn)換器決定,默認(rèn)轉(zhuǎn)換器為json)
o.toString();
//2.2.將 ONode 轉(zhuǎn)為 json
o.toJson();
//2.3.將 ONode 轉(zhuǎn)為XxxModel (例:UserModel)
o.toObject(UserModel.class);
//>將 ONode 轉(zhuǎn)為 Map 或 List 或 常規(guī)值
o.toObject(null);
//>將 ONode 轉(zhuǎn)為 自動(dòng)類(lèi)型的 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.一個(gè)應(yīng)用示例(極光推送的rest api調(diào)用)
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.數(shù)據(jù)遍歷
//遍歷Object數(shù)據(jù) 方案1
o.forEach((k,v)->{
//...
});
//遍歷Object數(shù)據(jù) 方案2
for(Map.Entry<String,ONode> kv : n.obj().entrySet()){
//...
}
//遍歷Array數(shù)據(jù) 方案1
o.forEach((v)->{
//...
});
//遍歷Array數(shù)據(jù) 方案2
for(ONode v : o.ary()){
//..
}
三密浑、混合加載與轉(zhuǎn)換代碼演示
List<UserModel> list = new ArrayList<>();
//..
ONode o = ONode.load("{code:1,msg:'succeed'}");
o.get("data").get("list").fill(list);
關(guān)于三組類(lèi)型接口的設(shè)計(jì)(Json object,array,value)
- 關(guān)于
json object
的操作
-obj() -> Map<String,ONode> //獲取節(jié)點(diǎn)對(duì)象數(shù)據(jù)結(jié)構(gòu)體(如果不是對(duì)象類(lèi)型福荸,會(huì)自動(dòng)轉(zhuǎn)換)
-contains(key:String) -> bool //是否存在對(duì)象子節(jié)點(diǎn)?
-get(key:String) -> child:ONode //獲取對(duì)象子節(jié)點(diǎn)(不存在,生成新的子節(jié)點(diǎn)并返回)
-getOrNull(key:String) -> child:ONode //獲取對(duì)象子節(jié)點(diǎn)(不存在肴掷,返回null)
-getNew(key:String) -> child:ONode //生成新的對(duì)象子節(jié)點(diǎn)敬锐,會(huì)清除之前的數(shù)據(jù)
-set(key:String,val:Object) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)(會(huì)自動(dòng)處理類(lèi)型)//val:為常規(guī)類(lèi)型或ONode
-setNode(key:String,val:ONode) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn),值為ONode類(lèi)型
-setAll(obj:ONode) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)呆瞻,將obj的子節(jié)點(diǎn)搬過(guò)來(lái)
-setAll(map:Map<String,T>) ->self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)台夺,將map的成員搬過(guò)來(lái)
-setAll(map:Map<String,T>, (n,t)->..) ->self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn),將map的成員搬過(guò)來(lái)痴脾,并交由代理處置
-remove(key:String) //移除對(duì)象的子節(jié)點(diǎn)
-forEach((k,v)->..) //遍歷對(duì)象的子節(jié)點(diǎn)
- 關(guān)于
json array
的操作
-ary() -> List<ONode> //獲取節(jié)點(diǎn)數(shù)組數(shù)據(jù)結(jié)構(gòu)體(如果不是數(shù)組颤介,會(huì)自動(dòng)轉(zhuǎn)換)
-get(index:int) -> child:ONode //獲取數(shù)組子節(jié)點(diǎn)(超界,返回空節(jié)點(diǎn))
-getOrNull(index:int) -> child:ONode //獲取數(shù)組子節(jié)點(diǎn)(超界赞赖,返回null)
-addNew() -> child:ONode //生成新的數(shù)組子節(jié)點(diǎn)
-add(val) -> self:ONode //添加數(shù)組子節(jié)點(diǎn) //val:為常規(guī)類(lèi)型或ONode
-addNode(val:ONode) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)滚朵,值為ONode類(lèi)型
-addAll(ary:ONode) -> self:ONode //添加數(shù)組子節(jié)點(diǎn),將ary的子節(jié)點(diǎn)搬過(guò)來(lái)
-addAll(ary:Collection<T>) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)前域,將ary的成員點(diǎn)搬過(guò)來(lái)
-addAll(ary:Collection<T>,(n,t)->..) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)辕近,將ary的成員點(diǎn)搬過(guò)來(lái),并交由代理處置
-removeAt(index:int) //移除數(shù)組的子節(jié)點(diǎn)
-forEach(v->..) //遍歷數(shù)組的子節(jié)點(diǎn)
- 關(guān)于
json value
的操作
-val() -> OValue //獲取節(jié)點(diǎn)值數(shù)據(jù)結(jié)構(gòu)體(如果不是值類(lèi)型匿垄,會(huì)自動(dòng)轉(zhuǎn)換)
-val(val:Object) -> self:ONode //設(shè)置節(jié)點(diǎn)值 //val:為常規(guī)類(lèi)型或ONode
-getString() //獲取值并以string輸出 //如果節(jié)點(diǎn)為對(duì)象或數(shù)組移宅,則輸出json
-getShort() //獲取值并以short輸出...(以下同...)
-getInt()
-getBoolean()
-getLong()
-getDate()
-getFloat()
-getDouble()
-getDouble(scale:int)
-getChar()
關(guān)于序列化的特點(diǎn)
- 對(duì)象
{"@type":"...","a":1,"b":"2"}
- 數(shù)組(可以精準(zhǔn)反序列化列表類(lèi)型;需要特性開(kāi)啟)
[{"@type":"..."},[1,2,3]]
關(guān)于Json path的支持
- 支持完整的
Json path
的選擇操作
支持操作 | 說(shuō)明 |
---|---|
$ | 查詢(xún)根元素(或當(dāng)前元素)椿疗。 這將啟動(dòng)所有路徑表達(dá)式(可以不輸)漏峰。 |
* | 通配符,必要時(shí)可用任何地方的名稱(chēng)或數(shù)字届榄。 |
.. | 深層掃描浅乔。 必要時(shí)在任何地方可以使用名稱(chēng)。 |
.<name> | 點(diǎn)铝条,表示子節(jié)點(diǎn) |
['<name>' (, '<name>')] | 括號(hào)表示子項(xiàng) |
[<number> (, <number>)] | 數(shù)組索引或索引 |
[start:end] | 數(shù)組切片操作 |
例:n.select("$.store.book[0].title")
或 n.select("$['store']['book'][0]['title']")
附:完整的接口字典
//初始化操作
//
-asObject() -> self:ONode //將節(jié)點(diǎn)切換為對(duì)象
-asArray() -> self:ONode //將節(jié)點(diǎn)切換為數(shù)組
-asValue() -> self:ONode //將節(jié)點(diǎn)切換為值
-asNull() -> self:ONode //將節(jié)點(diǎn)切換為null
//檢測(cè)操作
//
-isObject() -> bool //檢查節(jié)點(diǎn)是否為對(duì)象
-isArray() -> bool //檢查節(jié)點(diǎn)是否為數(shù)組
-isValue() -> bool //檢查節(jié)點(diǎn)是否為值
-isNull() -> bool //檢查節(jié)點(diǎn)是否為null
//公共
//
-nodeData() -> ONodeData //獲取節(jié)點(diǎn)數(shù)據(jù)
-nodeType() -> ONodeType //獲取節(jié)點(diǎn)類(lèi)型
-cfg(cfg:Constants) -> self:ONode //切換配置
-cfg() -> Constants //獲取配置
-build(n->..) -> self:ONode //節(jié)點(diǎn)構(gòu)建表達(dá)式
-select(jpath:String) -> new:ONode //使用JsonPath表達(dá)式選擇節(jié)點(diǎn)(默認(rèn)緩存路徑編譯)
-select(jpath:String, useStandard:boolean)-> new:ONode //useStandard:使用標(biāo)準(zhǔn)模式,默認(rèn)非標(biāo)準(zhǔn)
-select(jpath:String, useStandard:boolean, cacheJpath:boolean)-> new:ONode //cacheJpath:是否緩存javaPath編譯成果靖苇,默認(rèn)緩存
-clear() //清除子節(jié)點(diǎn)席噩,對(duì)象或數(shù)組有效
-count() -> int //子節(jié)點(diǎn)數(shù)量,對(duì)象或數(shù)組有效
//值操作
//
-val() -> OValue //獲取節(jié)點(diǎn)值數(shù)據(jù)結(jié)構(gòu)體(如果不是值類(lèi)型顾复,會(huì)自動(dòng)轉(zhuǎn)換)
-val(val:Object) -> self:ONode //設(shè)置節(jié)點(diǎn)值 //val:為常規(guī)類(lèi)型或ONode
-getString() //獲取值并以string輸出 //如果節(jié)點(diǎn)為對(duì)象或數(shù)組,則輸出json
-getShort() //獲取值并以short輸出...(以下同...)
-getInt()
-getBoolean()
-getLong()
-getDate()
-getFloat()
-getDouble()
-getDouble(scale:int)
-getChar()
//對(duì)象操作
//
-obj() -> Map<String,ONode> //獲取節(jié)點(diǎn)對(duì)象數(shù)據(jù)結(jié)構(gòu)體(如果不是對(duì)象類(lèi)型鲁捏,會(huì)自動(dòng)轉(zhuǎn)換)
-readonly() -> self:ONode //只讀形態(tài)(get時(shí)芯砸,不添加子節(jié)點(diǎn))
-contains(key:String) -> bool //是否存在對(duì)象子節(jié)點(diǎn)?
-rename(key:String,newKey:String) -> self:ONode //重命名子節(jié)點(diǎn)并返回自己
-get(key:String) -> child:ONode //獲取對(duì)象子節(jié)點(diǎn)(不存在,生成新的子節(jié)點(diǎn)并返回)
-getOrNull(key:String) -> child:ONode //獲取對(duì)象子節(jié)點(diǎn)(不存在给梅,返回null)
-getNew(key:String) -> child:ONode //生成新的對(duì)象子節(jié)點(diǎn)假丧,會(huì)清除之前的數(shù)據(jù)
-set(key:String,val:Object) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)(會(huì)自動(dòng)處理類(lèi)型)
-setNode(key:String,val:ONode) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn),值為ONode類(lèi)型
-setAll(obj:ONode) -> self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)动羽,將obj的子節(jié)點(diǎn)搬過(guò)來(lái)
-setAll(map:Map<String,T>) ->self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn)包帚,將map的成員搬過(guò)來(lái)
-setAll(map:Map<String,T>, (n,t)->..) ->self:ONode //設(shè)置對(duì)象的子節(jié)點(diǎn),將map的成員搬過(guò)來(lái)运吓,并交由代理處置
-remove(key:String) //移除對(duì)象的子節(jié)點(diǎn)
-forEach((k,v)->..) -> self:ONode //遍歷對(duì)象的子節(jié)點(diǎn)
//數(shù)組操作
//
-ary() -> List<ONode> //獲取節(jié)點(diǎn)數(shù)組數(shù)據(jù)結(jié)構(gòu)體(如果不是數(shù)組渴邦,會(huì)自動(dòng)轉(zhuǎn)換)
-get(index:int) -> child:ONode //獲取數(shù)組子節(jié)點(diǎn)(超界,返回空節(jié)點(diǎn))
-getOrNull(index:int) -> child:ONode //獲取數(shù)組子節(jié)點(diǎn)(超界拘哨,返回null)
-addNew() -> child:ONode //生成新的數(shù)組子節(jié)點(diǎn)
-add(val) -> self:ONode //添加數(shù)組子節(jié)點(diǎn) //val:為常規(guī)類(lèi)型或ONode
-addNode(val:ONode) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)谋梭,值為ONode類(lèi)型
-addAll(ary:ONode) -> self:ONode //添加數(shù)組子節(jié)點(diǎn),將ary的子節(jié)點(diǎn)搬過(guò)來(lái)
-addAll(ary:Collection<T>) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)倦青,將ary的成員點(diǎn)搬過(guò)來(lái)
-addAll(ary:Collection<T>,(n,t)->..) -> self:ONode //添加數(shù)組子節(jié)點(diǎn)瓮床,將ary的成員點(diǎn)搬過(guò)來(lái),并交由代理處置
-removeAt(index:int) //移除數(shù)組的子節(jié)點(diǎn)
-forEach(v->..) -> self:ONode //遍歷數(shù)組的子節(jié)點(diǎn)
//特性操作(不破壞數(shù)據(jù)的情況上产镐,添加數(shù)據(jù)隘庄;或用于構(gòu)建xml dom)
//
-attrGet(key:String) -> String //獲取特性
-attrSet(key:String,val:String) -> self:ONode //設(shè)置特性
-attrForeach((k,v)->..) -> self:ONode //遍歷特性
//轉(zhuǎn)換操作
//
-toString() -> String //轉(zhuǎn)為string (由字符串轉(zhuǎn)換器決定,默認(rèn)為json)
-toJson() -> String //轉(zhuǎn)為json string
-toData() -> Object //轉(zhuǎn)為數(shù)據(jù)結(jié)構(gòu)體(Map,List,Value)
-toObject(clz:Class<T>) -> T //轉(zhuǎn)為java object(clz=Object.class:自動(dòng)輸出類(lèi)型)
-to(toer:Toer, clz:Class<T>) -> T //將當(dāng)前節(jié)點(diǎn)通過(guò)toer進(jìn)行轉(zhuǎn)換
-to(toer:Toer) -> T //將當(dāng)前節(jié)點(diǎn)通過(guò)toer進(jìn)行轉(zhuǎn)換
//填充操作(為當(dāng)前節(jié)點(diǎn)填充數(shù)據(jù)癣亚;source 為 String 或 java object)
-fill(source:Object) -> self:ONode //填充數(shù)據(jù)
-fill(source:Object, fromer:Fromer) -> self:ONode //填充數(shù)據(jù)丑掺,由fromer決定處理
/**
* 以下為靜態(tài)操作
**/
//加載操作(source 為 String 或 java object)
//
+load(source:Object) -> new:ONode //加載數(shù)據(jù)
+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 //反序列化