Mule 4 DataWeave 2.3:JSON扁平化生成数据库记录报错解决
Mule 4 DataWeave 2.3:嵌套JSON扁平化实现(解决数组转对象报错)
问题背景
需要将嵌套JSON对象扁平化,把嵌套对象/数组的键用.拼接成新键,生成可直接插入数据库的单条记录,避免丢失原JSON键名。自定义testMe函数运行时报错:Cannot coerce Array ([{"supplierId.": "123456"}]) to Object,调试发现输入数组未被解构,newRecords数组也未正确填充对象。
错误原因
核心问题是未正确处理数组类型的嵌套结构:要么直接把数组当作对象处理,要么遍历数组时没有生成合法的键值对,导致返回了数组而非扁平对象,后续类型转换时触发报错。
正确实现代码
下面是通用的扁平化函数,支持嵌套对象和数组的键拼接,同时处理顶层输入为数组的场景:
%dw 2.3 output application/json // 递归扁平化对象/数组,用.拼接嵌套键,数组元素用索引区分 fun flattenObject(obj: Any, prefix: String = "") = obj match { // 处理嵌套对象:遍历键值对,递归拼接前缀 case is Object -> obj flatMap ((value, key) -> flattenObject(value, if (prefix == "") key else prefix ++ "." ++ key) ) // 处理数组:遍历元素并带上索引,递归后合并结果 case is Array -> obj mapIndexed ((item, index) -> flattenObject(item, if (prefix == "") index as String else prefix ++ "." ++ index as String) ) reduce ((item, acc) -> acc ++ item) // 基础类型:直接生成键值对 else -> {(prefix): obj} } // 处理顶层输入:如果是数组则逐个扁平化,否则直接处理 fun processInput(input: Any) = input match { case is Array -> input map flattenObject($) case is Object -> flattenObject(input) else -> input } --- processInput(payload)
代码说明
flattenObject函数:- 递归遍历所有嵌套结构,对象直接拼接父键与子键;数组元素则用
索引拼接键名(如items.0.itemId) - 最终将所有嵌套结构转换为扁平的键值对对象,避免返回数组导致类型转换错误
- 递归遍历所有嵌套结构,对象直接拼接父键与子键;数组元素则用
processInput函数:- 处理顶层输入的数组场景,确保每个数组元素都被解构并扁平化,解决输入数组未被处理的问题
- 类型匹配:通过
match语法精准处理对象、数组、基础类型,避免类型不兼容的报错
示例验证
假设输入JSON:
{ "orderId": "ORD123", "supplier": { "supplierId": "123456", "name": "ABC Corp" }, "items": [ { "itemId": "ITEM001", "quantity": 2 }, { "itemId": "ITEM002", "quantity": 1 } ] }
输出结果:
{ "orderId": "ORD123", "supplier.supplierId": "123456", "supplier.name": "ABC Corp", "items.0.itemId": "ITEM001", "items.0.quantity": 2, "items.1.itemId": "ITEM002", "items.1.quantity": 1 }
该结果完全符合数据库插入的扁平记录要求,无原键名丢失,也不会触发数组转对象的报错。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

