如果項目需求是從某些復(fù)雜的json里面取值進行計算,用jsonpath IK(ik-expression)來處理十分方便,jsonpath用來取json里面的值然后用IK自帶的函數(shù)進行計算,如果是特殊的計算那就自定義IK方法搞定,配置化很方便. 下面簡單介紹下jsonpath的使用方法,主要測試都在JsonPathDemo類里面: 下面是一個簡單的java項目demo: 注意: 其中他的max,min,avg,stddev函數(shù)只能類似于如下處理: //正確寫法 但是感覺很雞肋
context.read('$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)');
不能傳入list 感覺比較雞肋,如果傳入list 他會報錯(如下錯誤寫法): //這樣會報錯
Object maxV = context.read('$.max($.result.records[*].loan_type)');
//這樣也會報錯
Object maxV = context.read('$.result.records[*].loan_type.max()');
//如果json文件中是這樣:'loan_type':'2',也會報錯,'loan_type':2 這樣才被認(rèn)為是數(shù)字
報錯信息都一樣,如下: Exception in thread 'main' com.jayway.jsonpath.JsonPathException: Aggregation function attempted to calculate value using empty array
JsonPathDemo是一個測試demo: public class JsonPathDemo {
public static void main(String[] args) {
String json = FileUtils.readFileByLines('demo.json');
ReadContext context = JsonPath.parse(json);
//1 返回所有name
List<String> names = context.read('$.result.records[*].name');
//['張三','李四','王五']
System.out.println(names);
//2 返回所有數(shù)組的值
List<Map<String, String>> objs = context.read('$.result.records[*]');
//[{'name':'張三','pid':'500234199212121212','mobile':'18623456789','applied_at':'3','confirmed_at':'5','confirm_type':'overdue','loan_type':'1','test':'mytest','all':'2'},{'name':'李四','pid':'500234199299999999','mobile':'13098765432','applied_at':'1','confirmed_at':'','confirm_type':'overdue','loan_type':'3','all':'3'},{'name':'王五','pid':'50023415464654659','mobile':'1706454894','applied_at':'-1','confirmed_at':'','confirm_type':'overdue','loan_type':'3'}]
System.out.println(objs);
//3 返回第一個的name
String name0 = context.read('$.result.records[0].name');
//張三
System.out.println(name0);
//4 返回下標(biāo)為0 和 2 的數(shù)組值
List<String> name0and2 = context.read('$.result.records[0,2].name');
//['張三','王五']
System.out.println(name0and2);
//5 返回下標(biāo)為0 到 下標(biāo)為1的 的數(shù)組值 這里[0:2] 表示包含0 但是 不包含2
List<String> name0to2 = context.read('$.result.records[0:2].name');
//['張三','李四']
System.out.println(name0to2);
//6 返回數(shù)組的最后兩個值
List<String> lastTwoName = context.read('$.result.records[-2:].name');
//['李四','王五']
System.out.println(lastTwoName);
//7 返回下標(biāo)為1之后的所有數(shù)組值 包含下標(biāo)為1的
List<String> nameFromOne = context.read('$.result.records[1:].name');
//['李四','王五']
System.out.println(nameFromOne);
//8 返回下標(biāo)為3之前的所有數(shù)組值 不包含下標(biāo)為3的
List<String> nameEndTwo = context.read('$.result.records[:3].name');
//['張三','李四','王五']
System.out.println(nameEndTwo);
//9 返回applied_at大于等于2的值
List<Map<String, String>> records = context.read('$.result.records[?(@.applied_at >= '2')]');
//[{'name':'張三','pid':'500234199212121212','mobile':'18623456789','applied_at':'3','confirmed_at':'5','confirm_type':'overdue','loan_type':'1','test':'mytest','all':'2'}]
System.out.println(records);
//10 返回name等于李四的值
List<Map<String, String>> records0 = context.read('$.result.records[?(@.name == '李四')]');
//[{'name':'李四','pid':'500234199299999999','mobile':'13098765432','applied_at':'1','confirmed_at':'','confirm_type':'overdue','loan_type':'3'}]
System.out.println(records0);
//11 返回有test屬性的數(shù)組
List<Map<String, String>> records1 = context.read('$.result.records[?(@.test)]');
//[{'name':'張三','pid':'500234199212121212','mobile':'18623456789','applied_at':'3','confirmed_at':'5','confirm_type':'overdue','loan_type':'1','test':'mytest','all':'2'}]
System.out.println(records1);
//12 返回有test屬性的數(shù)組
List<String> list = context.read('$..all');
//['1','4','2','3']
System.out.println(list);
//12 以當(dāng)前json的某個值為條件查詢 這里ok為1 取出records數(shù)組中applied_at等于1的數(shù)組
List<String> ok = context.read('$.result.records[?(@.applied_at == $['ok'])]');
//['1','4','2','3']
System.out.println(ok);
//13 正則匹配
List<String> regexName = context.read('$.result.records[?(@.pid =~ /.*999/i)]');
//[{'name':'李四','pid':'500234199299999999','mobile':'13098765432','applied_at':'1','confirmed_at':'','confirm_type':'overdue','loan_type':'3','all':'3'}]
System.out.println(regexName);
//14 多條件
List<String> mobile = context.read('$.result.records[?(@.all == '2' || @.name == '李四' )].mobile');
//['18623456789','13098765432']
System.out.println(mobile);
//14 查詢數(shù)組長度
Integer length01 = context.read('$.result.records.length()');
//3
System.out.println(length01);
//15 查詢list里面每個對象長度
List<Integer> length02 = context.read('$.result.records[?(@.all == '2' || @.name == '李四' )].length()');
//[9,8]
System.out.println(length02);
//16 最大值
Object maxV = context.read('$.max($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)');
//3.0
System.out.println(maxV);
//17 最小值
Object minV = context.read('$.min($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)');
//1.0
System.out.println(minV);
//18 平均值
double avgV = context.read('$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)');
//2.3333333333333335
System.out.println(avgV);
//19 標(biāo)準(zhǔn)差
double stddevV = context.read('$.stddev($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)');
//0.9428090415820636
System.out.println(stddevV);
//20 讀取一個不存在的
String haha = context.read('$.result.haha');
//拋出異常
//Exception in thread 'main' com.jayway.jsonpath.PathNotFoundException: No results for path: $['result']['haha']
//at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
//at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
//at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)
//at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89)
//at cn.lijie.jsonpath.JsonPathDemo.main(JsonPathDemo.java:58)
//at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
//at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
//at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
//at java.lang.reflect.Method.invoke(Method.java:498)
//at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
System.out.println(haha);
}
}
pom文件引入: <dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.3.0</version>
</dependency>
其中demo.json是一個測試json: {
'action': '/interface.service/xxx/queryBlackUserData',
'all': '1',
'result': {
'count': 2,
'tenant_count': 2,
'records': [
{
'name': '張三',
'pid': '500234199212121212',
'mobile': '18623456789',
'applied_at': '3',
'confirmed_at': '5',
'confirm_type': 'overdue',
'loan_type': 1,
'test': 'mytest',
'all': '2'
},
{
'name': '李四',
'pid': '500234199299999999',
'mobile': '13098765432',
'applied_at': '1',
'confirmed_at': '',
'confirm_type': 'overdue',
'loan_type': 3,
'all': '3'
},
{
'name': '王五',
'pid': '50023415464654659',
'mobile': '1706454894',
'applied_at': '-1',
'confirmed_at': '',
'confirm_type': 'overdue',
'loan_type': 3
}
],
'all': '4'
},
'code': 200,
'subtime': '1480495123550',
'status': 'success',
'ok': 3
}
FileUtils類是用于讀取xx.json文件為字符串的json: public class FileUtils {
/**
* 以行為單位讀取文件,常用于讀面向行的格式化文件
*/
public static String readFileByLines(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
String str = '';
try {
InputStream is = FileUtils.class.getClassLoader().getResourceAsStream(fileName);
reader = new BufferedReader(new InputStreamReader(is));
String tempString = null;
int line = 1;
// 一次讀入一行,直到讀入null為文件結(jié)束
while ((tempString = reader.readLine()) != null) {
// 顯示行號
str = tempString;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return str;
}
}
|
|