开源软件名称:snack3
开源软件地址:https://gitee.com/noear/snack3
开源软件介绍:
Snack3 for java一个微型JSON + Jsonpath框架 基于jdk8,80kb。支持:序列化反序列化、解析和转换、Json path 查询。 <dependency> <groupId>org.noear</groupId> <artifactId>snack3</artifactId> <version>3.2.16</version></dependency> Snack3 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计。其下一切数据都以ONode 表示,ONode 也即 One node 之意,代表任何类型,也可以转换为任何类型。 - 强调文档树的操控和构建能力
- 做为中间媒体,方便不同格式互转
- 高性能
Json path 查询(兼容性和性能很赞) - 支持
序列化、反序列化 - 基于 无参构造函数 + 字段 操作实现(因注入而触发动作的风险,不会有)
随便放几个示例//demo0::字符串化String json = ONode.stringify(user); //demo1::序列化// -- 输出带@typeString json = ONode.serialize(user); //demo2::反序列化// -- json 有已带@typeUserModel user = ONode.deserialize(json); // -- json 可以不带@type (clz 申明了)UserModel user = ONode.deserialize(json, UserModel.class); // -- json 可以不带@type,泛型方式输出(类型是已知的)List<UserModel> list = ONode.deserialize(json, (new ArrayList<UserModel>(){}).getClass()); //demo3::转为ONodeONode o = ONode.loadStr(json); //将json String 转为 ONodeONode o = ONode.loadObj(user); //将java Object 转为 ONode//demo3.1::转为ONode,取子节点进行序列化ONode o = ONode.loadStr(json);UserModel user = o.get("user").toObject(UserModel.class);//demo4:构建json数据(极光推送的rest api调用)public static void push(Collection<String> alias_ary, String text) { ONode data = new ONode().build((d)->{ d.getOrNew("platform").val("all"); d.getOrNew("audience").getOrNew("alias").addAll(alias_ary); d.getOrNew("options") .set("apns_production",false); d.getOrNew("notification").build(n->{ n.getOrNew("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);}//demo5:取值o.get("name").getString();o.get("num").getInt();o.get("list").get(0).get("lev").getInt();//demo5.1::取值并转换UserModel user = o.get("user").toObject(UserModel.class); //取user节点,并转为UserModel//demo5.2::取值或新建并填充o.getOrNew("list2").fill("[1,2,3,4,5,5,6]");//demo6::json path //不确定返回数量的,者会返回array类型//找到所有的187开头的手机号,改为186,最后输出修改后的jsono.select("$..mobile[?(@ =~ /^187/)]").forEach(n->n.val("186")).toJson();//找到data.list[1]下的的mobile字段,并转为longo.select("$.data.list[1].mobile").getLong();//查找所有手机号,并转为List<String> List<String> list = o.select("$..mobile").toObject(List.class);//查询data.list下的所有mobile,并转为List<String>List<String> list = o.select("$.data.list[*].mobile").toObject(List.class);//找到187手机号的用户,并输出List<UserModel>List<UserModel> list = o.select("$.data.list[?(@.mobile =~ /^187/)]") .toObjectList(UserModel.class);//或List<UserModel> list = o.select("$.data.list[?(@.mobile =~ /^187/)]") .toObjectList(UserModel.class);//demo7:遍历//如果是个Objecto.forEach((k,v)->{ //...});//如果是个Arrayo.forEach((v)->{ //...});//demo8:自定义编码Options options = Options.def();options.addEncoder(Date.class, (data, node) -> { node.val().setString(DateUtil.format(data, "yyyy-MM-dd"));});String json = ONode.loadObj(orderModel, options).toJson(); 关于序列化的特点对象(可以带type){"a":1,"b":"2"}//或{"@type":"...","a":1,"b":"2"} 数组[1,2,3]//或[{"@type":"...","a":1,"b":"2"},{"@type":"...","a":2,"b":"10"}] 关于Json path的支持- 字符串使用单引号,例:['name']
- 过滤操作用空隔号隔开,例:[?(@.type == 1)]
支持操作 | 说明 |
---|
$ | 表示根元素 | @ | 当前节点(做为过滤表达式的谓词使用) | * | 通用配配符,可以表示一个名字或数字。 | .. | 深层扫描。 可以理解为递归搜索。 | .<name> | 表示一个子节点 | ['<name>' (, '<name>')] | 表示一个或多个子节点 | [<number> (, <number>)] | 表示一个或多个数组下标(负号为倒数) | [start:end] | 数组片段,区间为[start,end),不包含end(负号为倒数) | [?(<expression>)] | 过滤表达式。 表达式结果必须是一个布尔值。 |
支持过滤操作符(操作符两边要加空隔 ) | 说明 |
---|
== | left等于right(注意1不等于'1') | != | 不等于 | < | 小于 | <= | 小于等于 | > | 大于 | >= | 大于等于 | =~ | 匹配正则表达式[?(@.name =~ /foo.*?/i)] | in | 左边存在于右边 [?(@.size in ['S', 'M'])] | nin | 左边不存在于右边 |
支持尾部函数 | 说明 |
---|
min() | 计算数字数组的最小值 | max() | 计算数字数组的最大值 | avg() | 计算数字数组的平均值 | sum() | 计算数字数组的汇总值(新加的) |
例:n.select("$.store.book[0].title") 或 n.select("$['store']['book'][0]['title']") 例:n.select("$..book.price.min()") //找到最低的价格 Snack3 接口字典//快捷构建//+newValue() -> new:ONode 创建值类型节点+newObject() -> new:ONode 创建对象类型节点+newArray() -> new:ONode 创建数组类型节点//初始化操作//-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 //获取当前节点类型-options(opts:Options) -> self:ONode //切换选项-options() -> Options //获取选项-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 //子节点数量,对象或数组有效-readonly() -> self:ONode //只读形态(get时,不添加子节点)//值操作//-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> //获取节点对象数据结构体(如果不是对象类型,会自动转换)-contains(key:String) -> bool //是否存在对象子节点?-rename(key:String,newKey:String) -> self:ONode //重命名子节点并返回自己-get(key:String) -> child:ONode //获取对象子节点(不存在,返回空节点)***-getOrNew(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类型(需要在外部初始化类型,建议用set(k,v))-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 //获取数组子节点(不存在,返回空节点)-getOrNew(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类型(需要在外部初始化类型,建议用add(v))-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:自动输出类型)-toObjectList(clz:Class<T>) -> List<T> //转为java list,用于简化:toObject((new ArrayList<User>()).getClass()) 这种写法-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, Feature... features) -> self:ONode //填充数据-fillObj(source:Object, Feature... features) -> self:ONode //填充数据-fillStr(source:String, Feature... features) -> self:ONode //填充数据/** * 以下为静态操作**///加载操作(source 为 String 或 java object)//+load(source:Object) -> new:ONode //加载数据+load(source:Object, Feature... features) -> 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+loadStr(source:String, Feature... features) -> new:ONode //仅String//加载 java object+loadObj(source:Object) -> new:ONode //仅java object+loadObj(source:Object, Feature... features) -> new:ONode //仅java object//字符串化操作//+stringify(source:Object) -> String //字符串化;//序列化操作//+serialize(source:Object) -> String //序列化(带@type属性)+deserialize(source:String) -> T //反序列化+deserialize(source:String, clz:Class<?>) -> T //反序列化 |
请发表评论