WSO2聚合API中查询参数无法正确填充问题求助
问题排查与修复方案
根源分析
- 未在资源URI模板中声明查询参数:你的
<resource>节点uri-template仅定义了/getData,未包含oc和cid参数,导致Synapse无法自动将请求中的这两个参数解析到query.param.*属性中,get-property('query.param.oc')自然返回空值。 - Endpoint参数引用方式错误:直接在Endpoint的
uri-template里用{oc}无法正确引用自定义属性,必须通过get-property()表达式显式获取属性值。 - 属性作用域限制:自定义属性默认
default作用域下,clone的子序列可能无法正常访问,需要调整为axis2作用域确保跨序列可见。
修复步骤
1. 声明资源URI的查询参数
修改<resource>的uri-template,显式包含oc和cid参数,让Synapse自动捕获请求参数:
<resource methods="GET" uri-template="/getData?oc={oc}&cid={cid}">
2. 调整属性作用域与Endpoint引用方式
把属性的作用域改为axis2,同时在Endpoint的URI模板中用表达式引用属性:
<!-- 调整属性作用域为axis2,确保clone子序列能访问 --> <property expression="get-property('query.param.oc')" name="oc" scope="axis2" type="INTEGER"/> <property expression="get-property('query.param.cid')" name="cid" scope="axis2" type="INTEGER"/> <!-- Office服务Endpoint:用get-property引用属性 --> <http method="get" uri-template="http://localhost:8290/services/officesDS/getOffice?OfficeCode={get-property('axis2', 'oc')}"> <!-- Product服务Endpoint:用get-property引用属性 --> <http method="get" uri-template="http://localhost:8290/services/productsDS/getProduct?category_id={get-property('axis2', 'cid')}">
3. 可选:添加参数校验(避免空值报错)
在设置属性后加入校验逻辑,提前拦截空参数请求:
<filter xpath="not(get-property('axis2', 'oc') = '')"> <then/> <else> <payloadFactory media-type="json"> <format>{"error": "oc参数为必填项"}</format> </payloadFactory> <respond/> </else> </filter> <filter xpath="not(get-property('axis2', 'cid') = '')"> <then/> <else> <payloadFactory media-type="json"> <format>{"error": "cid参数为必填项"}</format> </payloadFactory> <respond/> </else> </filter>
修改后的完整API配置
<?xml version="1.0" encoding="UTF-8"?> <api context="/aggregate" name="CombinedAPI" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="GET" uri-template="/getData?oc={oc}&cid={cid}"> <inSequence> <property expression="get-property('query.param.oc')" name="oc" scope="axis2" type="INTEGER"/> <property expression="get-property('query.param.cid')" name="cid" scope="axis2" type="INTEGER"/> <!-- 参数校验 --> <filter xpath="not(get-property('axis2', 'oc') = '')"> <then/> <else> <payloadFactory media-type="json"> <format>{"error": "oc参数为必填项"}</format> </payloadFactory> <respond/> </else> </filter> <filter xpath="not(get-property('axis2', 'cid') = '')"> <then/> <else> <payloadFactory media-type="json"> <format>{"error": "cid参数为必填项"}</format> </payloadFactory> <respond/> </else> </filter> <clone> <target> <sequence> <call> <endpoint> <http method="get" uri-template="http://localhost:8290/services/usersDS/getUsers"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>1</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <property expression="get-property('response')" name="userResponse" scope="default" type="STRING"/> </sequence> </target> <target> <sequence> <call> <endpoint> <http method="get" uri-template="http://localhost:8290/services/officesDS/getOffice?OfficeCode={get-property('axis2', 'oc')}"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>1</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <log level="full" separator=","> <property expression="get-property('response')" name="Office Service Response"/> </log> <property expression="get-property('response')" name="officeResponse" scope="default" type="STRING"/> </sequence> </target> <target> <sequence> <call> <endpoint> <http method="get" uri-template="http://localhost:8290/services/productsDS/getProduct?category_id={get-property('axis2', 'cid')}"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>1</progressionFactor> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <log level="full" separator=","> <property expression="get-property('response')" name="Product Service Response"/> </log> <property expression="get-property('response')" name="productResponse" scope="default" type="STRING"/> </sequence> </target> </clone> <aggregate> <completeCondition> <messageCount max="-1" min="3"/> </completeCondition> <onComplete aggregateElementType="root" expression="json-eval($)"> <log level="full" separator=","> <property expression="json-eval($)" name="Aggregated Response"/> </log> <property expression="json-eval($)" name="aggregatedResponse" scope="default" type="STRING"/> <log level="full" separator=","> <property expression="get-property('aggregatedResponse')" name="Final Aggregated Response"/> </log> <respond/> </onComplete> </aggregate> </inSequence> <outSequence/> <faultSequence/> </resource> </api>
内容的提问来源于stack exchange,提问作者Mohammed Khammeri
相关产品推荐
相关产品推荐

