簡介:一個能夠通過JSON配置(特定的語法)來處理復雜數據轉換的工具。
比如將API響應轉換為內部系統所需的格式,或者處理來自不同來源的數據結構差異。例如,將嵌套的JSON結構扁平化,或者重命名字段,合并多個字段等。
名稱含義:
-
JSON + Bolt:
JSON 是工具處理的數據格式。
?Bolt?(閃電)象征快速和高效,暗示 Jolt 能夠像閃電一樣快速完成 JSON 數據的轉換。
Bolt?的logo就是一個閃電??標志 -
在社區中,Jolt 的名稱被解讀為 ?JSON Transformation Language 的縮寫,強調其作為 JSON 轉換語言的定位。
-
項目地址:https://github.com/bazaarvoice/jolt
-
在線驗證工具:https://jolt-demo.appspot.com/#inception
使用
1. 引入maven依賴
- pom.xml
<dependency><groupId>com.bazaarvoice.jolt</groupId><artifactId>jolt-core</artifactId><version>0.1.7</version>
</dependency>
<dependency><groupId>com.bazaarvoice.jolt</groupId><artifactId>json-utils</artifactId><version>0.1.7</version>
</dependency>
2. 編寫Jolt轉換規范(json格式)
- spec.json
[{"operation": "shift","spec": {"id": "id","orderType": "type","orderProductList": {"*": {"sampleNumber": "orderProductList[&1].number","id": "orderProductList[&1].id"}},"createTime": "createTime"}},{"operation": "modify-overwrite-beta","spec": {"id": "=toString(@(1,id))","createTime": "=concat(@(1,createTime), ' 00:00:00')"}}
]
3. Java集成示例
- DataTransformTool
import com.bazaarvoice.jolt.Chainr;
import com.bazaarvoice.jolt.JsonUtils;import java.util.List;/*** description: DataTransformTool <br>* date: 2025/3/13 11:47 <br>* author: Boo <br>* version: 1.0 <br>*/
public class DataTransformTool {public static String transform(String inputJson, String specPath) {List chainrSpecJSON = JsonUtils.classpathToList( specPath );Chainr chainr = Chainr.fromSpec( chainrSpecJSON );Object transformedOutput = chainr.transform( JsonUtils.jsonToObject(inputJson) );return JsonUtils.toJsonString( transformedOutput );}}
- Test.java
public static main(String[] args) {String inputJson = "{" +" \"id\": 123456789," +" \"orderType\": \"orderTypecsss\"," +" \"orderProductList\": [" +" {\"sampleNumber\": \"number001\", \"id\": 2}," +" {\"sampleNumber\": \"SKU456\", \"id\": 1}" +" ]," +" \"createTime\": \"2025-03-13\"" +" }";System.out.println(DataTransformTool.transform(inputJson, "spec.json"));}
- 運行結果
{"id": "123456789","type": "orderTypecsss","orderProductList": [{"number": "number001","id": 2},{"number": "SKU456","id": 1}],"createTime": "2025-03-13 00:00:00"
}
Jolt 轉換規范的核心語法
AI整理,仔細辨別
核心操作類型
操作類型 | 用途 | 示例 |
---|---|---|
shift | 字段映射/結構調整 | “oldField”: “newField” |
modify-overwrite-beta | 數據修改(類型轉換/計算) | “field”: “=toUpper” |
default | 設置默認值 | “field”: “defaultVal” |
remove | 刪除字段 | “fieldToRemove”: “” |
sort | 字段排序 | 無參數,直接使用 |
核心操作符及示例
1. ?shift
用途:字段重映射、結構調整。
語法:將輸入路徑映射到輸出路徑。
示例:
{"operation": "shift","spec": {"inputField": "output.parent.child", // 簡單映射"nested.input.value": "output.value", // 嵌套映射"array[*].id": "output.ids[]" // 數組展開}
}
2. ?default
用途:設置默認值(字段不存在時生效)。
語法:
{"operation": "default","spec": {"output.role": "guest", // 單值默認"output.tags": ["default"] // 數組默認}
}
3. ?remove
用途:刪除指定字段。
語法:
{"operation": "remove","spec": {"unusedField": "", // 刪除字段"nested.tempData": "" // 刪除嵌套字段}
}
4. ?sort
用途:按字母序排序對象鍵。
語法:
{ "operation": "sort" }
5. ?cardinality
用途:強制字段為單值或數組。
語法:
{"operation": "cardinality","spec": {"output.roles": "array", // 強制為數組"output.name": "single" // 強制為單值}
}
6. ?modify-overwrite-beta
用途:覆蓋或修改字段值(需 Jolt 擴展庫)。
語法:
{"operation": "modify-overwrite-beta","spec": {"output.score": "=toDouble(@(1,input.score))" // 轉換為浮點數}
}
7. ?modify-default-beta
用途:條件默認值(類似 default 但支持表達式)。
語法:
{"operation": "modify-default-beta","spec": {"output.status": "=if (isPresent(@(1,input.status))) then @(1,input.status) else 'pending'"}
}
路徑語法規則
?點號.:表示嵌套字段,如 user.address.city。
?通配符*:匹配任意字段或數組元素:
users[].name:提取所有 users 元素的 name。
data..value:匹配 data 下的所有子字段的 value。
?數組索引[n]:定位數組的特定位置,如 items[0].id。
?轉義\:若字段名包含 . 或 *,需轉義,如 field\.with\.dots。
鏈式操作示例
json
[// 第一步:字段映射{"operation": "shift","spec": {"firstName": "user.name","age": "user.details.age"}},// 第二步:添加默認值{"operation": "default","spec": {"user.role": "guest","user.details.active": true}},// 第三步:刪除冗余字段{"operation": "remove","spec": {"user.details.age": ""}}
]
輸入:
{ "firstName": "John", "age": 30 }
輸出:
{"user": {"name": "John","role": "guest","details": {"active": true}}
}
高級技巧
- 動態鍵名:使用 & 引用輸入字段的值作為鍵:
{"operation": "shift","spec": {"userType": "output.&" // 將 userType 的值作為鍵}
}
輸入 { “userType”: “admin” } → 輸出 { “output”: { “admin”: “admin” } }。
- ?條件邏輯:通過 modify 系列操作符實現復雜條件:
{"operation": "modify-overwrite-beta","spec": {"output.discount": "=if (@(1,price) > 100) then 0.1 else 0"}
}
- ?數組聚合:將多個字段合并為數組:
{"operation": "shift","spec": {"tags": "output.tags[]"}
}
注意事項
- 大小寫敏感:字段名和路徑嚴格區分大小寫。
- ?路徑不存在:若輸入路徑不存在,操作符會靜默忽略。
- 性能優化:復雜嵌套或通配符可能影響性能,盡量簡化規則。