使用DataWeave转换JSON为Multipart请求的技术问题
使用DataWeave将JSON转换为Multipart请求的解决方案
问题概述
需将JSON数组转换为符合OData批量请求规范的multipart/mixed类型请求,当前面临以下技术难点:
- 无法为请求段添加带URI参数的请求方法与头部
- 无法遍历输入数组生成对应请求片段
- 无法正确构建多层嵌套的multipart边界(batch与changeset)
输入示例
[ { "add": 1, "city": "hyd" }, { "add": 2, "city": "Kol" } ]
期望输出
POST /test/api HTTP Request Headers: Content-Type:multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b Accept:application/json OData-Version:4.0 OData-MaxVersion:4.0 If-None-Match:null HTTP Request Body: --batch_36522ad7-fc75-4b56-8c71-56071383e77b Content-Type: multipart/mixed; boundary=changeset_8a6f6ebe-e9c9-44a2-b980-c33a69370eb4 --changeset_8a6f6ebe-e9c9-44a2-b980-c33a69370eb4 Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: 1 POST /info/post HTTP/1.1 OData-Version: 4.0 OData-MaxVersion: 4.0 Content-Type: application/json;odata.metadata=minimal Accept: application/json;odata.metadata=minimal Accept-Charset: UTF-8 User-Agent: Microsoft.OData.Client/7.5.4 { "address": 1, "city": "hyd" } --changeset_8a6f6ebe-e9c9-44a2-b980-c33a69370eb4 Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: 2 POST /info/post HTTP/1.1 OData-Version: 4.0 OData-MaxVersion: 4.0 Content-Type: application/json;odata.metadata=minimal Accept: application/json;odata.metadata=minimal Accept-Charset: UTF-8 User-Agent: Microsoft.OData.Client/7.5.4 { "address": 2, "city": "kol" } --changeset_8a6f6ebe-e9c9-44a2-b980-c33a69370eb4 Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: 3 PATCH /info/post (address='1',city='kol')?cross-company=true HTTP/1.1 OData-Version: 4.0 OData-MaxVersion: 4.0 Content-Type: application/json;odata.metadata=minimal Accept: application/json;odata.metadata=minimal Accept-Charset: UTF-8 User-Agent: Microsoft.OData.Client/7.5.4 { "ready": "Yes" } --changeset_8a6f6ebe-e9c9-44a2-b980-c33a69370eb4-- --batch_36522ad7-fc75-4b56-8c71-56071383e77b--
解决方案代码
%dw 2.0 output application/java // 生成唯一的batch和changeset边界 var batchBoundary = "batch_" ++ uuid() var changesetBoundary = "changeset_" ++ uuid() // 定义复用的通用请求头 var commonRequestHeaders = "OData-Version: 4.0\nOData-MaxVersion: 4.0\nContent-Type: application/json;odata.metadata=minimal\nAccept: application/json;odata.metadata=minimal\nAccept-Charset: UTF-8\nUser-Agent: Microsoft.OData.Client/7.5.4" // 遍历输入数组生成POST请求片段 fun buildPostSegments(items) = items map ((item, idx) -> "--$(changesetBoundary)\nContent-Type: application/http\nContent-Transfer-Encoding: binary\nContent-ID: $(idx + 1)\n\nPOST /info/post HTTP/1.1\n$(commonRequestHeaders)\n\n{\n\"address\": $(item.add),\n\"city\": \"$(lower(item.city))\"\n}\n" ) // 构建带URI参数的PATCH请求片段 var patchSegment = "--$(changesetBoundary)\nContent-Type: application/http\nContent-Transfer-Encoding: binary\nContent-ID: 3\n\nPATCH /info/post (address='1',city='kol')?cross-company=true HTTP/1.1\n$(commonRequestHeaders)\n\n{\n\"ready\": \"Yes\"\n}\n" // 拼接完整请求体 var requestBody = "--$(batchBoundary)\nContent-Type: multipart/mixed; boundary=$(changesetBoundary)\n\n" ++ (buildPostSegments(payload) joinBy "") ++ patchSegment ++ "--$(changesetBoundary)--\n--$(batchBoundary)--" // 组装完整的请求内容(含请求行、头部与体) var fullRequest = "POST /test/api\nHTTP Request Headers:\n\nContent-Type: multipart/mixed; boundary=$(batchBoundary)\nAccept: application/json\nOData-Version:4.0\nOData-MaxVersion:4.0\nIf-None-Match:null\n\nHTTP Request Body:\n\n$(requestBody)" --- fullRequest
关键解决点说明
- 多层边界处理:使用
uuid()生成唯一的batch和changeset标识符,避免边界冲突,确保multipart结构符合规范。 - 数组遍历:通过
map函数遍历输入数组,为每个元素生成对应的POST请求片段,利用索引值自动生成Content-ID。 - 请求方法与头部配置:
- 定义通用请求头变量实现复用,减少冗余代码
- 直接拼接带路径参数、查询参数的请求行,满足带URI参数的请求需求
内容的提问来源于stack exchange,提问作者Prabhu Kumar
相关产品推荐
相关产品推荐

