TALEND调用REST API后如何提取JSON中指定字段存入全局变量
Talend REST API返回结果提取executionId与triggerTimestamp的正确实现方案
背景说明
调用REST API获取JSON格式返回结果,需要提取每条记录对应的executionId和triggerTimestamp存入全局变量,现有两种返回场景。
场景说明
场景1:Talend Job返回的转义JSON
返回结果为嵌套转义结构,Body字段内的JSON携带反斜杠转义字符,无法直接解析,示例如下:
{"read":[{"Body":"{\"items\":[{\"executionId\":\"a0613a31-d16d-4c4d-9279-4564a86cdd44\",\"startTimestamp\":\"2021-09-15T22:30:26.854Z\",\"triggerTimestamp\":\"2021-09-15T22:30:27.209Z\",\"userId\":\"user1\",\"status\":\"dispatching\",\"runtime{\"type\":\"REMOTE_ENGINE_CLUSTER\"},\"executionStatus\":\"DISPATCHING_FLOW\"},{\"executionId\":\"49a56eb1-f3c7-4f26-9554-8fa88acde38b\",\"startTimestamp\":\"2021-09-15T22:29:15.999Z\",\"triggerTimestamp\":\"2021-09-15T22:29:16.447Z\",\"userId\":\"user1\",\"executionType\":\"MANUAL\",\"status\":\"dispatching\",\"runtime\":{\"type\":\"REMOTE_ENGINE_CLUSTER\"},\"executionStatus\":\"DISPATCHING_FLOW\"}],\"limit\":100,\"offset\":0,\"total\":2}","ERROR_CODE":null}]}
场景2:WEB URL调用返回的正常JSON
返回标准JSON结构,BODY存储在context.statusbody变量中,示例如下:
{ "items": [{ "executionId": "4f679c12-d8d7-4dd7-89d5-507a94503988", "startTimestamp": "2021-09-14T19:05:01.854Z", "triggerTimestamp": "2021-09-14T19:05:02.385Z", "userId": "user1", "taskId": "60b7f6d31c6e394de0163d35", "status": "dispatching", "runtime": { "type": "REMOTE_ENGINE_CLUSTER" }, "executionStatus": "DISPATCHING_FLOW" }, { "executionId": "4f40b04c-1ac1-42ea-9a36-7c25b1b17fe8", "startTimestamp": "2021-09-14T19:00:24.769Z", "triggerTimestamp": "2021-09-14T19:00:25.122Z", "userId": "user1", "taskId": "60b7f6d31c6e394de0163d35", "executionType": "SCHEDULED", "status": "dispatching", "runtime": { "type": "REMOTE_ENGINE_CLUSTER" }, "executionStatus": "DISPATCHING_FLOW" } ], "limit": 100, "offset": 0, "total": 2 }
原有方案问题
使用substring硬截取的方式容错性极低,只要JSON结构出现字段顺序调整、空格增减等变化,就会出现取值错误,不建议使用。
正确实现方案
优先使用JSON结构化解析的方式实现,可选择低代码组件方案或者Java代码方案,Talend环境默认内置org.json解析包,无需额外导入依赖。
方案1:低代码组件实现(推荐)
无需编写代码,直接使用Talend自带组件完成解析:
- 拿到API返回结果后,连接
tExtractJSONFields组件 - 根据场景配置JSON解析路径:
- 场景1:先提取
Body字段的字符串内容,再将内容送入tExtractJSONFields组件,配置遍历路径为$.items[*] - 场景2:直接配置遍历路径为
$.items[*]
- 场景1:先提取
- 映射输出字段:
executionId对应JSON路径executionIdtriggerTimestamp对应JSON路径triggerTimestamp
- 将输出字段直接赋值给上下文变量或全局变量即可。
方案2:tJava组件代码实现
如果需要自定义处理逻辑,可在tJava组件中编写如下代码:
场景1处理代码
import org.json.JSONObject; import org.json.JSONArray; // 请将下方responseStr替换为你实际获取的完整API返回字符串 JSONObject outerJson = new JSONObject(responseStr); JSONArray readArr = outerJson.getJSONArray("read"); JSONObject readObj = readArr.getJSONObject(0); // 自动解析转义的Body字符串为JSON对象 String bodyStr = readObj.getString("Body"); JSONObject bodyJson = new JSONObject(bodyStr); JSONArray items = bodyJson.getJSONArray("items"); // 遍历所有记录取值 for(int i=0; i<items.length(); i++){ JSONObject item = items.getJSONObject(i); String executionId = item.getString("executionId"); String triggerTime = item.getString("triggerTimestamp"); // 存入上下文变量,多条记录可存储为List或用索引区分存入globalMap globalMap.put("executionId_"+i, executionId); globalMap.put("triggerTime_"+i, triggerTime); // 如果只需要第一条记录,直接赋值即可 if(i == 0){ context.executionID = executionId; context.triggerTime = triggerTime; } }
场景2处理代码
import org.json.JSONObject; import org.json.JSONArray; JSONObject bodyJson = new JSONObject(context.statusbody); JSONArray items = bodyJson.getJSONArray("items"); // 遍历所有记录取值 for(int i=0; i<items.length(); i++){ JSONObject item = items.getJSONObject(i); String executionId = item.getString("executionId"); String triggerTime = item.getString("triggerTimestamp"); // 变量存储逻辑同上 globalMap.put("executionId_"+i, executionId); globalMap.put("triggerTime_"+i, triggerTime); context.executionID = executionId; context.triggerTime = triggerTime; }
内容的提问来源于stack exchange,提问作者sarah
相关产品推荐
相关产品推荐

