Snack3 一個新的微型JSON框架
一個作品,一般表達作者的一個想法。因為大家想法不同,所有作品會有區別。就做技術而言,因為有很多有區別的框架,所以大家可以選擇的框架很豐富。
snack3。基於jdk8
,60kb
,無其它依賴,非常小巧。
- 強調文檔樹的鏈式操控和構建能力
- 強調中間媒體,方便不同格式互轉
- 支持
序列化、反序列化
- 支持
Json path
查詢
ONode 即 One node
之意;借簽了 Javascript
所有變量由 var
申明,及 Xml dom
一切都是 Node
的設計。這應該也是與別的框架不同之處。
設計思路
-
ONode
是一個接口界面,內部由nodeType
和nodeData
組成。通過nodeType
進行類型識別,通過nodeData
容納所有的類型數據。 -
采用
Fromer
->ONode
->Toer
的架構設計。這是重要的一個設計,可使轉換具有很強的擴展能力,Fromer
和Toer
各做一半工作,也可各自切換(有好處也會有壞處)。 -
強調非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 //反序列化