fastJson对jsonPath的支持
使用场景
很多时候我们调用上游接口拿到的返回值是json字符串,如果不存在上游共享的公用返回值类,那么下游可能会直接使用JsonObject之类的动态对象类承接这份数据。这时候对于很深的的属性取值是非常复杂的
我们大概会这样写
String getvalue(String jsonStr){
JSONObject json =JSONObject.parseObject(jsonStr);
String d = null;
//比如我们要取出a.b.c.d,但是我们不确定a是不是null,b是不是null,c是不是ull
//如果要考考虑对象或者是数组判断的值会更加的多
JSONObject a = json.getJSONObject("a");
if( a != null ){
JSONObject b = json.getJSONObject("b");
if( b != null ){
JSONObject c = json.getJSONObject("c");
if( c != null ){
d = json.getString("d");
}
}
}
return d;
}
上面这种写法是非常恶心的,尤其是在层次比较多的时候,如果使用jsonPath一切就变得简单了
String getvalue2(String jsonStr){
return JSONPath.compile("$.a.d.c.d").eval( jsonStr,String.class );
}
哪些框架支持jsonPath?
fastjson是有jsonPath支持的,redis的json类型,mysql的json类型也都有对jsonPath的支持
hutools 的ison格式化也是对jsonPath有支持的,支持程度不如fastjson
jayway 也是对jsonPath有支持的,但是它默认处理方案是路径不存在报错,不好用
fastJson对jsonPath的支持
可以取值的数据源支持json字符串,JSONObject对象,支持普通java对象
JSONPath jsonpath = new JSONPath("$.name");
JSONPath jsonpath2 = new JSONPath("$.a.b.c[1]");
//可以直接取json字符串的数据
String jsonDate = "{\"a\":{\"b\":{\"c\":[1,2,3]}}}";
System.out.println( jsonpath.eval( jsonDate ) );
System.out.println( jsonpath2.eval( jsonDate ) );
//可以直接取对象的数据
Goods goods = new Goods();
goods.setName("zhangsan");
System.out.println( jsonpath.eval( goods ) );
System.out.println( jsonpath2.eval( goods ) );
//可以直接取jsonObject的数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("name","jsonZhangsan");
System.out.println( jsonpath.eval( jsonObject ) );
System.out.println( jsonpath2.eval( jsonObject ) );
可以指定返回值数据类型
//需要指定类型
System.out.println("指定类型数据存在:" + jsonpath.<String>eval( jsonObject,String.class ) );
System.out.println("指定类型数据不存在:" + jsonpath2.<String>eval( jsonObject,String.class ) );
可以静态方法获取数据
它的内部实现是通过多层Segment去一层一层的去取数据
compile是有模版缓存比直接new JsonPath效率高。
read方法底层也用的evel方法
String read = JSONPath.<String>read(JSONObject.toJSONString(goods), jsonpath.getPath(), String.class);
Object eval = JSONPath.eval(goods, jsonpath.getPath());
//这是最基本方法,静态方法JSONPath.<String>read(),JSONPath.eval(),都是调用的它
//JSONPath.compile底层自带缓存,缓存了1024个path,比直接调用 new JsonPath的效率高
//推荐使用这个方法
String eval1 = JSONPath.compile(jsonpath.getPath()).<String>eval(goods, String.class);
//对于多层的jsonPath,实际的做法是一层一层取获取
//private JSONPath.Segment[]
//比如a.b.c.d 会被分成 4个Segment
一些常见的方法
取值
//获取属性
String v1 = JSONPath.compile("$.name").<String>eval(jsonObject1, String.class);
System.out.println("eval:" + v1);
//extract比eval用起来复杂,看注释应该比eval出的早
Object v2 = JSONPath.compile("$.name").extract( new DefaultExtJSONParser(jsonObject1.toJSONString()));
System.out.println("extract:" + v2);
删除,修改,取size,得到keys
//删除
System.out.println("删除前:" + jsonObject1 );
JSONPath.compile("$.name").remove(jsonObject1);
System.out.println("删除后:" + jsonObject1 );
//修改值
JSONPath.compile("$.name").set(jsonObject1,"李四");
System.out.println("修改以后:" + jsonObject1 );
//取size
System.out.println("size1:" + JSONPath.compile("$").size(jsonObject1));
System.out.println("size2:" + JSONPath.compile("$").size(goods));
System.out.println("size3:" + JSONPath.compile("$").size(Arrays.asList(1,2,3)));
//得到所有key
System.out.println("keySet-json对象:" + JSONPath.compile("$").keySet(jsonObject1) );
System.out.println("keySet-对象:" + JSONPath.compile("$").keySet(goods) );
判断值和path是否存在
//判断path是否存在
System.out.println("path是否存在:" + JSONPath.compile("$.name").contains(jsonObject1) );
//判断值是否存在
System.out.println("是否存在值"+ JSONPath.compile("$.name").containsValue(jsonObject1,"zhangsan") );
System.out.println("是否存在值"+ JSONPath.compile("$.name").containsValue(jsonObject1,"李四") );
输出path
//输出path
String path = JSONPath.compile("$.name").getPath();
System.out.println("path:" + path);
对数组追加值
//数组,和jsonArray都可以
JSONArray array = new JSONArray();
array.add(1);
array.add(2);
array.add(3);
JSONPath.compile("$").arrayAdd(array,4);
System.out.println("arrayAdd:" + array );
hutool对jsonPath的支持
/**
* hutool对jsonnPath的支持
*/
@Test
public void hutool_jsonpath(){
JSONObject obj = JSONUtil.parseObj( Goods.randomGoods() );
//路径不存在,默认不会报错
System.out.println( obj.getByPath("$.name.age.name2",String.class) );
System.out.println( JSONUtil.getByPath(obj,"$.name","") );
}
jayway对jsonPath的支持
jayway是spring-boot-starter自带的jsonPath工具
使用例子
/**
* jayway对jsonnPath的支持
*/
@Test
public void jayway_jsonpath(){
Object read = JsonPath.read(JSONUtil.toJsonStr(Goods.randomGoods()),"$.name");
//不存在的路径会报错
//Object read = JsonPath.read(JSONUtil.toJsonStr(Goods.randomGoods()),"$.name.age.name2");
System.out.println(read);
}
能耍的时候就一定要耍,不能耍的时候一定要学。
--天道酬勤,贵在坚持posted on 2024-07-25 16:51 zhangyukun 阅读(394) 评论(0) 编辑 收藏 举报