WSO2 Iterate组件聚合JSON响应异常:返回<jsonObject />问题排查
WSO2 Iterate聚合返回
<jsonObject />问题排查与解决 问题原因
- 属性名不匹配:PayloadFactory中引用的
CreatedDate、ModifiedDate与实际定义的属性create_date、modified_date格式不一致,导致生成的JSON字段值为空,聚合无有效内容。 - 聚合配置错误:
aggregateElementType="root"会破坏JSON对象的聚合逻辑,导致结构异常。expression="json-eval($)"无法正确提取迭代分支的JSON消息体。- 聚合后用
$body/*提取响应,无法适配JSON转OM后的节点结构,导致response属性为空。
- 分支消息传递缺失:Iterate分支的
then块未显式传递生成的Payload到聚合组件,部分分支被<drop/>后,聚合可能无法正确收集所有有效消息。
修正后的代理配置
<?xml version="1.0" encoding="UTF-8"?> <proxy name="TestProxy" startOnLoad="true" transports="http https vfs" xmlns="http://ws.apache.org/ns/synapse"> <target> <inSequence> <property name="contentType" scope="transport" type="STRING" value="text/csv"/> <smooks config-key="smooksConf"> <input type="text"/> <output type="xml"/> </smooks> <property name="messageType" scope="axis2" type="STRING" value="application/json"/> <property expression="get-property('Credentials')" name="CREDENTIALS" scope="default" type="OM" xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"/> <property expression="$ctx:CREDENTIALS//*[local-name()='TOKEN']" name="TOKEN" scope="default" type="STRING"/> <iterate continueParent="true" expression="//Parents/parent" id="Iterate-over-json" sequential="true" xmlns:ns="http://org.apache.synapse/xsd"> <target> <sequence> <property expression="json-eval($.parent.id)" name="parentId" scope="default" type="STRING"/> <call> <endpoint> <http method="get" uri-template="{{api-1}}"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <property expression="json-eval($.data.id)" name="SourceNumber" scope="default" type="STRING"/> <property expression="json-eval($.data.name)" name="Name" scope="default" type="STRING"/> <property expression="json-eval($.data.parent_id)" name="SourceParentNumber" scope="default" type="STRING"/> <property expression="json-eval($.data.is_visible)" name="isActive" scope="default" type="STRING"/> <call> <endpoint> <http method="get" uri-template="{{api-2}}"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <property expression="json-eval($.data[0].date_created)" name="create_date" scope="default" type="STRING"/> <property expression="json-eval($.data[0].date_modified)" name="modified_date" scope="default" type="STRING"/> <property expression="json-eval($.data[0].flag)" name="DateFlag" scope="default" type="STRING"/> <filter regex="true" source="get-property('isActive')"> <then> <property name="EndDate" scope="default" type="STRING" value=""/> <property name="Active" scope="default" type="STRING" value="TRUE"/> </then> <else> <property expression="get-property('modified_date')" name="EndDate" scope="default" type="STRING"/> <property name="Active" scope="default" type="STRING" value="FALSE"/> </else> </filter> <filter regex="valid" source="get-property('DateFlag')"> <then> <payloadFactory media-type="json"> <format> { "SourceNumber" : "$1", "Name" : "$2", "SourceParentNumber" : "$3", "DateCreated" : "$4", "DateLastModified" : "$5", "Active" : "$6" } </format> <args> <arg evaluator="xml" expression="$ctx:SourceNumber"/> <arg evaluator="xml" expression="$ctx:Name"/> <arg evaluator="xml" expression="$ctx:SourceParentNumber"/> <arg evaluator="xml" expression="$ctx:create_date"/> <arg evaluator="xml" expression="$ctx:modified_date"/> <arg evaluator="xml" expression="$ctx:Active"/> </args> </payloadFactory> <respond/> </then> <else> <payloadFactory media-type="json"> <format>{}</format> <args/> </payloadFactory> <respond/> </else> </filter> </sequence> </target> </iterate> <aggregate id="Iterate-over-json"> <completeCondition> <messageCount max="-1" min="-1"/> </completeCondition> <onComplete expression="$body"> <property expression="json-eval($)" name="response" scope="operation" type="STRING"/> </onComplete> </aggregate> <payloadFactory media-type="json"> <format>$1</format> <args> <arg evaluator="xml" expression="get-property('operation','response')"/> </args> </payloadFactory> <log> <property expression="json-eval($)" name="Aggregated-response"/> </log> </inSequence> <outSequence/> <faultSequence/> </target> <parameter name="transport.vfs.Streaming">true</parameter> <parameter name="transport.PollInterval">15</parameter> <parameter name="transport.vfs.MaxRetryCount">1</parameter> <parameter name="transport.vfs.FileURI">sftp://{{sftp_path}}</parameter> <parameter name="transport.vfs.ContentType">text/plain</parameter> <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter> <parameter name="transport.vfs.MoveAfterFailure">sftp://{{sftp_path}}</parameter> <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter> <parameter name="transport.vfs.FileNamePattern">.*.csv</parameter> <parameter name="transport.vfs.MoveAfterProcess">sftp://{{sftp_path}}</parameter> </proxy>
关键修改点说明
- 属性名修正:将PayloadFactory中
CreatedDate/ModifiedDate改为create_date/modified_date,匹配实际定义的属性名。 - 分支消息传递:在
then和else块末尾添加<respond/>,确保每个分支的消息都能传递到聚合组件;替换<drop/>为空JSON对象传递,避免聚合因等待缺失消息而异常。 - 聚合配置优化:移除
aggregateElementType="root",使用默认的数组聚合;将onComplete的expression改为$body,并通过json-eval($)提取JSON字符串到response属性。 - 日志优化:修改日志输出的表达式为
json-eval($),直接打印JSON格式的聚合结果。
内容的提问来源于stack exchange,提问作者stels
相关产品推荐
相关产品推荐

