今天有个临时需求,需要将很多json数据添加一个key value。
当听到这个需求,第一眼想到的便是fastjson,构造一堆list,map什么的,感觉特复杂。想着想着突然脑海里飘过XPath,然鹅XPath是基于xml,就百度一下看看有没有json path。居然还真有个JsonPath。。。突然发现自己很孤陋寡闻。
既然有了,那就学习一下,下面就说说今天的使用心得。
https://github.com/json-path/JsonPath
看网址像是官方的,可以在线测试表达式,还是蛮好使的
http://jsonpath.com/
https://goessner.net/
// https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path
compile group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
XPath | JSONPath | Description |
---|---|---|
/ | $ | the root object/element |
. | @ | the current object/element |
/ | . or [] | child operator |
.. | n/a | parent operator |
// | .. | recursive descent. JSONPath borrows this syntax from E4X. |
* | * | wildcard. All objects/elements regardless their names. |
@ | n/a | attribute access. JSON structures don’t have attributes. |
[] | [] | subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator. |
| | [,] | Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set. |
n/a | [start: end:step] | array slice operator borrowed from ES4. |
[] | ?() | applies a filter (script) expression. |
n/a | () | script expression, using the underlying script engine. |
() | n/a | grouping in Xpath |
XPath | JSONPath | Description |
---|---|---|
/store/book/author | $.store.book[*].author | the authors of all books in the store |
//author | $..author | all authors |
/store/* | $.store.* | all things in store, which are some books and a red bicycle. |
/store//price | $.store..price | the price of everything in the store. |
//book[3] | $..book[2] | the third book |
//book[last()] | $…book[(@.length-1)] $…book[-1:] |
the last book in order. |
//book[position() < 3] | $…book[0,1] $…book[:2] |
the first two books |
//book[isbn] | $..book[?(@.isbn)] | filter all books with isbn number |
//book[price<10] | $…book[?(@.price<10)] | filter all books cheapier than 10 |
//* | $..* | all Elements in XML document. All members of JSON structure. |
使用JsonPath修改Json数据
{
"apis":[
{
"ctime":"2018-11-08 16:01:16",
"mtime":"2019-02-20 22:11:42",
"modifierId":1,
"creatorId":1,
"apiId":"1",
"authType":"none",
"version":"v3",
"path": "/test",
"httpMethod":"POST",
"serviceCode":"resource",
"cateCode":"server-task",
"mappingProtocol":"DUBBO",
"modifyVersion":1,
"onlineVersion":1,
"isOnline":"Y",
"isCached":"N",
"cachedTime":10000,
"requestMode":"MAPPING",
"servCreatorId":1134,
"requestMappingParam":{
"requestParams":[
{
"name":"tenantId",
"type":"Long",
"paramLocation":"Query",
"isRequired":true,
"defaultValue":""
},
{
"name":"userId",
"type":"Long",
"paramLocation":"Query",
"isRequired":true,
"defaultValue":""
},
{
"name":"taskId",
"type":"Long",
"paramLocation":"Query",
"isRequired":false,
"description":"ID"
},
{
"name":"taskName",
"type":"String",
"paramLocation":"Query",
"isRequired":true,
"defaultValue":"",
"description":"名称"
}
]
}
"dubboParamMappings": {
"leafParamMappings": [
{
"paramName":"tenantId",
"paramType":"java.lang.Long",
"paramMapping":"tenantId"
}
]
}
}
]
}
apis是个列表,列表包含很多map集合。
每个map代表一个api,api中包含requestParams。
其中需要将requestParams中tenantId和userId参数加上headerMapping。
"requestParams":[
{
"name":"tenantId",
"type":"Long",
"paramLocation":"Query",
"isRequired":true,
"defaultValue":"",
"headerMapping":"X-Access-TenantId" // 需要添加的东西
},
{
"name":"userId",
"type":"Long",
"paramLocation":"Query",
"isRequired":true,
"defaultValue":"",
"headerMapping":"X-Access-UserId" // 需要添加的东西
},
首先,读取json文件:
InputStream inputStream = Files.newInputStream(Paths.get("/Users/admin/Downloads/resource.json"));
构造整个文档
DocumentContext document = JsonPath.parse(inputStream);
在指定位置添加key value
document.put("$.apis[*].requestMappingParam.requestParams[?(@.name==\"tenantId\"[email protected])]", "headerMapping", "X-Access-TenantId");
document.put("$.apis[*].requestMappingParam.requestParams[?(@.name==\"userId\"[email protected])]", "headerMapping", "X-Access-UserId");
写入修改后的json
Files.write(Paths.get("/tmp/resource.json")), context.jsonString().getBytes());
没几行代码便完成了