使用请求数组中的相应元素丰富响应数组

时间:2017-07-19 06:34:41

标签: wso2 wso2esb

输入请求:

[
    {
        "id" : "1",     
        "make" : "NAHB"
    },
    {
        "id" : "2",
        "make" : "Honda"
    },
    {
        "id" : "3",
        "make" : "Samsung"
    }
]

我正在使用iterate,将上面数组的每个元素作为请求发送到后端服务(在myactual项目中,这不是那么简单的服务,即它的响应非常复杂,有很多数组和子数组(子数组)为了更好地理解问题,我保持这样。)

后端服务的响应由AggregateMediator汇总在一个soap xml中。

以下是AggregateMediator的回复

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <Information>
            <jsonObject>
                <id>3</id>
                <name>Mobile</name>
                <model>S8</model>
            </jsonObject>
            <jsonObject>
                <id>2</id>          
                <name>Car</name>
                <model>Amaze</model>
            </jsonObject>
            <jsonObject>
                <id>1</id>
                <name>Home</name>
                <area>5000sqft</area>
            </jsonObject>
        </Information>
    </soapenv:Body>
</soapenv:Envelope>

我想使用输入请求丰富上面的AggregateMediator响应。 即我想合并输入请求和后端服务的输出。(id在它们之间是常见的。)

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <Information>
            <jsonObject>
                <id>3</id>
                <name>Mobile</name>
                <model>S8</model>
                <make>Samsung</make>
            </jsonObject>
            <jsonObject>
                <id>2</id>          
                <name>Car</name>
                <model>Amaze</model>
                <make>Honda</make>
            </jsonObject>
            <jsonObject>
                <id>1</id>
                <name>Home</name>
                <area>5000sqft</area>
                <make>NAHB</make>
            </jsonObject>
        </Information>
    </soapenv:Body>
</soapenv:Envelope>

我在调用后端服务之前将输入请求数组保留在属性中,并且能够在响应流中访问它。 但问题是“请求和响应都是数组”。我怎样才能在两个不同的数组上同时运行两个foreach,并在更新响应的每个数组元素之前匹配它们的id。

foreachTest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<api context="/foreschTest" name="foreachTest" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST GET" uri-template="/hi">
        <inSequence>
            <log level="full"/>
            <log level="custom">
                <property expression="//jsonArray" name="message"/>
            </log>
            <property expression="//jsonArray" name="req" scope="default" type="STRING"/>
            <foreach expression="//jsonArray/jsonElement" id="Loop">
                <sequence>
                    <property expression="get-property('Loop_FOREACH_COUNTER')" name="countid" scope="default" type="STRING"/>
                    <!-- <enrich>
                        <source clone="true" property="INCOMING_REQUEST" type="property"/>
                        <target type="body"/>
                    </enrich>
                    <enrich>
                        <source clone="true" type="inline">
                            <id xmlns="">Y</id>
                        </source>
                        <target action="sibling" xpath="//jsonElement"/>
                    </enrich>  -->
                    <!--<enrich>
                        <source clone="true" type="property" property="INCOMING_REQUEST"></source>
                        <target action="replace" type="body"></target>
                    </enrich>   -->
                    <!-- Temporily commented   <enrich>
                        <source clone="true" type="inline">
                            <uniqueId xmlns="">Y</uniqueId>
                        </source>
                        <target action="child" xpath="//jsonElement/data[2]"/>
                    </enrich>
                    <enrich>
                        <source clone="true" property="countid" type="property"/>
                        <target xpath="//jsonElement/data[2]/uniqueId"/>
                    </enrich>  -->
                    <log level="custom">
                        <property expression="get-property('countid')" name="mgs7"/>
                    </log>
                    <log description="" level="custom">
                        <property expression="get-property('Loop_FOREACH_ORIGINAL_MESSAGE')" name="mgs5"/>
                        <property expression="get-property('Loop_FOREACH_COUNTER')" name="mgs6"/>
                        <property expression="//jsonElement" name="msg8"/>
                    </log>
                    <log description="" level="custom">
                        <property expression="//jsonElement/data[0]" name="msg9"/>
                        <property expression="//jsonElement/data[1]" name="msg10"/>
                        <property expression="//jsonElement/data[2]" name="msg11"/>
                    </log>
                </sequence>
            </foreach>
            <iterate expression="//jsonArray/jsonElement" id="1">
                <target>
                    <sequence>
                        <log level="custom">
                            <property name="msg2" value="&quot;Inside iterate&quot;"/>
                        </log>
                        <log level="full"/>
                        <send>
                            <endpoint key="modifyAgrRespEP"/>
                        </send>
                    </sequence>
                </target>
            </iterate>
        </inSequence>
        <outSequence>
            <property name="info" scope="default">
                <Information xmlns=""/>
            </property>
            <aggregate id="1">
                <completeCondition>
                    <messageCount max="-1" min="-1"/>
                </completeCondition>
                <onComplete enclosingElementProperty="info" expression="//jsonObject">
                    <log level="custom">
                        <property name="msg3" value="&quot;Inside Aggr&quot;"/>
                    </log>
                    <log level="full"/>
                    <foreach expression="//Information/jsonObject">
                        <sequence>
                            <log level="custom">
                                <property name="msg4" value="&quot;Inside Foreach&quot;"/>
                            </log>
                            <property expression="$body" name="agr" scope="default" type="STRING"/>
                            <log level="custom">
                                <property expression="get-property('agr')" name="agr"/>
                            </log>
                            <!--    <log level="full"/>  -->
                        </sequence>
                    </foreach>
                </onComplete>
            </aggregate>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

modifyAgrRes.xml:

<?xml version="1.0" encoding="UTF-8"?>
<api context="/mod" name="modifyAgrRes" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST GET" uri-template="/aggr">
        <inSequence>
            <log level="custom">
                <property name="message" value="&quot;Inside Modify Service *************************&quot;"/>
            </log>
            <log level="custom">
                <property expression="//jsonObject" name="location"/>
            </log>
            <switch source="//jsonObject/id">
                <case regex="1">
                    <enrich>
                        <source clone="true" type="inline">
                            <name xmlns="">Home</name>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                    <enrich>
                        <source clone="true" type="inline">
                            <area xmlns="">5000sqft</area>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                </case>
                <case regex="2">
                    <enrich>
                        <source clone="true" type="inline">
                            <name xmlns="">Car</name>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                    <enrich>
                        <source clone="true" type="inline">
                            <model xmlns="">Amaze</model>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                </case>
                <case regex="3">
                    <enrich>
                        <source clone="true" type="inline">
                            <name xmlns="">Mobile</name>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                    <enrich>
                        <source clone="true" type="inline">
                            <model xmlns="">S8</model>
                        </source>
                        <target action="child" xpath="//jsonObject"/>
                    </enrich>
                </case>
                <default/>
            </switch>
            <log level="custom">
                <property expression="//jsonObject" name="msg20"/>
            </log>
            <enrich>
                <source clone="true" xpath="//jsonObject"/>
                <target type="body"/>
             </enrich>
            <log level="full"/>
            <respond/>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

1 个答案:

答案 0 :(得分:0)

这是一个高级答案;我想你可以自己解决这些细节:

  1. 将输入($ body)复制到的新属性(inputBody) 开始
  2. 将$ ctx:inputBody转换为XML - 有关示例,请参阅此URL: https://docs.wso2.com/display/ESB481/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT
  3. 执行所有中间处理步骤
  4. 遍历$ ctx:inputBody属性,并为每一行
  5. 将/ id(currentId)和/ make(currentMake)转换为新属性
  6. 使用Enrich介体添加子项 / Information / jsonObject [id = $ ctx:currentId] / make,其值设置为 $ CTX:currentMake
  7. 如有必要,请转换回JSON。
  8. 我希望有所帮助。