You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSO2 Iterate组件聚合JSON响应异常:返回<jsonObject />问题排查

WSO2 Iterate聚合返回<jsonObject />问题排查与解决

问题原因

  1. 属性名不匹配:PayloadFactory中引用的CreatedDate、ModifiedDate与实际定义的属性create_date、modified_date格式不一致,导致生成的JSON字段值为空,聚合无有效内容。
  2. 聚合配置错误:
    • aggregateElementType="root" 会破坏JSON对象的聚合逻辑,导致结构异常。
    • expression="json-eval($)" 无法正确提取迭代分支的JSON消息体。
    • 聚合后用$body/*提取响应,无法适配JSON转OM后的节点结构,导致response属性为空。
  3. 分支消息传递缺失: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:49:53