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

WSO2 6.6.0中Call Mediator后Log Mediator无法获取Payload求助

问题描述

在WSO2中搭建了一个简单API,调用后端服务后无法获取到预期的响应Payload,Postman直接调用后端能正常返回结果,但API里各种方式都拿到空Payload或空对象。

API代码

<?xml version="1.0" encoding="UTF-8"?>
<api context="/dwh" name="dwhCallEp" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET" uri-template="/ep/{sysparam}">
        <inSequence>
            <log level="custom">
                <property name="START" value="call into dwh storage"/>
                <property expression="get-property('uri.var.sysparam')" name="sysparam"/>
            </log>
            <call>
                <endpoint>
                    <http method="get" statistics="enable" trace="enable" uri-template="http://my_path?sysparam={uri.var.sysparam}&amp;call_in_async_mode=false">
                        <timeout>
                            <duration>120000</duration>
                            <responseAction>fault</responseAction>
                        </timeout>
                        <suspendOnFailure>
                            <initialDuration>-1</initialDuration>
                            <progressionFactor>1.0</progressionFactor>
                        </suspendOnFailure>
                        <markForSuspension>
                            <retriesBeforeSuspension>0</retriesBeforeSuspension>
                        </markForSuspension>
                    </http>
                </endpoint>
            </call>
            <property expression="json-eval($[0])" name="JsonPayload" scope="default" type="STRING"/>
            <log level="full" separator="&#xa;">
                <property expression="$ctx:JsonPayload" name="JsonPayload"/>
            </log>
            <script language="js"><![CDATA[var payload = mc.getPayloadJSON();
                    var log = mc.getServiceLog();
                    log.info("payload_json : " + payload);
                    log.info("payload_json : " + JSON.stringify(payload));
                    mc.setProperty("payload_json",JSON.stringify(payload));]]></script>
            <log level="full" separator="&#xa;">
                <property name="payload" expression="json-eval($)" />
            </log>
            <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence>
            <payloadFactory media-type="xml">
                <format>
                    <error>$1</error>
                </format>
                <args>
                    <arg value="something go wrong!!!"/>
                </args>
            </payloadFactory>
        </faultSequence>
    </resource>
</api>

尝试过的方法

  • 使用level="full"的Log Mediator查看API返回的所有内容
  • 在Property Mediator中使用expression="json-eval($[0])"并记录其值到日志
  • 使用Script Mediator通过mc.getPayloadJSON()获取Payload,再用JSON.stringify(payload)转为字符串并存入属性
  • 在Property Mediator中使用expression="json-eval($)"并记录其值到日志

日志堆栈

[2024-02-01 11:07:51,198]  INFO {LogMediator} - {api:dwhCallEp} START = call into dwh storage, sysparam = pn_citytypes
[2024-02-01 11:07:51,201]  INFO {TRACE_LOGGER} - Sending message through endpoint : null resolving to address = http://erp.ukrposhta.loc/ws/api/_MR_DWH_KATALOG?sysparam={uri.var.sysparam}&call_in_async_mode=false
[2024-02-01 11:07:51,201]  INFO {TRACE_LOGGER} - SOAPAction: null
[2024-02-01 11:07:51,201]  INFO {TRACE_LOGGER} - WSA-Action: null
[2024-02-01 11:07:51,208]  INFO {TimeoutHandler} - This engine will expire all callbacks after GLOBAL_TIMEOUT: 120 seconds, irrespective of the timeout action, after the specified or optional timeout
[2024-02-01 11:07:51,254]  INFO {LogMediator} - {api:dwhCallEp} To: http://www.w3.org/2005/08/addressing/anonymous
WSAction: 
SOAPAction: 
MessageID: urn:uuid:d16a7929-5a73-4bd9-9a52-d2431aed680b
correlation_id: 04c91129-739e-4628-a206-ddb3bb047bc1
Direction: request
JsonPayload = 
Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
[2024-02-01 11:07:51,273]  INFO {CommonScriptMessageContext} - payload_json : [object Object]
[2024-02-01 11:07:51,274]  INFO {CommonScriptMessageContext} - payload_json : {}
[2024-02-01 11:07:51,275]  INFO {LogMediator} - {api:dwhCallEp} To: http://www.w3.org/2005/08/addressing/anonymous
WSAction: 
SOAPAction: 
MessageID: urn:uuid:d16a7929-5a73-4bd9-9a52-d2431aed680b
correlation_id: 04c91129-739e-4628-a206-ddb3bb047bc1
Direction: request
payload = 
Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>

核心疑问

所有方式都拿到空Payload或空对象,但Postman直接调用后端服务能返回预期Payload,问题出在哪里?


问题分析与解决方案

核心原因

当前使用的是无阻塞的<call>中介,它不会等待后端服务的响应返回就继续执行后续的中介逻辑,所以后续的Log、Property、Script中介都只能拿到初始的空请求Payload,而非后端的响应。

从日志里的Direction: request也能佐证这一点——正常拿到响应时,这个字段应该是response。

解决步骤

  1. 将<call>改为阻塞模式,添加<blocking/>子元素,让Synapse等待后端响应返回后再继续执行后续逻辑:
<call>
    <blocking/>
    <endpoint>
        <!-- 原endpoint配置保持不变 -->
    </endpoint>
</call>
  1. 确保后端返回的是JSON格式,并且响应的Content-Type头为application/json。如果后端返回的JSON没有正确设置Content-Type,Synapse可能无法自动识别为JSON Payload,导致json-eval和mc.getPayloadJSON()无法解析。可以在<call>之后添加<property>强制设置消息类型:
<call>
    <blocking/>
    <endpoint>...</endpoint>
</call>
<!-- 强制将消息类型设为JSON -->
<property name="messageType" value="application/json" scope="axis2"/>
  1. 验证修改后的流程:添加阻塞模式后,后续的中介就能正确获取到后端返回的响应Payload,日志中的Direction也会变为response。

修正后的完整inSequence示例

<inSequence>
    <log level="custom">
        <property name="START" value="call into dwh storage"/>
        <property expression="get-property('uri.var.sysparam')" name="sysparam"/>
    </log>
    <call>
        <blocking/>
        <endpoint>
            <http method="get" statistics="enable" trace="enable" uri-template="http://my_path?sysparam={uri.var.sysparam}&amp;call_in_async_mode=false">
                <timeout>
                    <duration>120000</duration>
                    <responseAction>fault</responseAction>
                </timeout>
                <suspendOnFailure>
                    <initialDuration>-1</initialDuration>
                    <progressionFactor>1.0</progressionFactor>
                </suspendOnFailure>
                <markForSuspension>
                    <retriesBeforeSuspension>0</retriesBeforeSuspension>
                </markForSuspension>
            </http>
        </endpoint>
    </call>
    <!-- 强制设置消息类型为JSON -->
    <property name="messageType" value="application/json" scope="axis2"/>
    <property expression="json-eval($[0])" name="JsonPayload" scope="default" type="STRING"/>
    <log level="full" separator="&#xa;">
        <property expression="$ctx:JsonPayload" name="JsonPayload"/>
    </log>
    <script language="js"><![CDATA[var payload = mc.getPayloadJSON();
            var log = mc.getServiceLog();
            log.info("payload_json : " + payload);
            log.info("payload_json : " + JSON.stringify(payload));
            mc.setProperty("payload_json",JSON.stringify(payload));]]></script>
    <log level="full" separator="&#xa;">
        <property name="payload" expression="json-eval($)" />
    </log>
    <respond/>
</inSequence>

内容的提问来源于stack exchange,提问作者Evgeniy Zhurenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:10:04