WSO2中基于JSON评估的条件路由配置问题排查
给定如下JSON数据:
{ "CustomerNames":{ "Update":[ { "CustName":"Name1", "id":"3" }, { "CustName":"Name3", "id":"32" } ], "Create":[ { "Name":"Name2" } ] } }
需求:当Update数组存在时调用UpdateCustomer序列;当Create数组存在时调用CreateCustomer序列。
尝试用Conditional Router Mediator实现条件路由,配置代码如下:
<property expression="json-eval($.CustomerNames.Update)" name="CREATE_PAYLOAD" scope="default" type="STRING"/> <property expression="json-eval($.CustomerNames.Create)" name="UPDATE_PAYLOAD" scope="default" type="STRING"/> <conditionalRouter continueAfter="true"> <conditionalRoute asynchronous="true" breakRoute="false"> <condition> <match regex="true" source="boolean(get-property('CREATE_PAYLOAD'))"/> </condition> <target sequence="CREATE_CUSTOMER"/> </conditionalRoute> <conditionalRoute asynchronous="true" breakRoute="false"> <condition> <match regex="true" source="boolean(get-property('UPDATE_PAYLOAD'))"/> </condition> <target sequence="UPDATE_CUSTOMER"/> </conditionalRoute> </conditionalRouter>
但配置未达到预期效果,请问哪里出错了?
你的配置存在三个核心问题:
属性名称完全搞反
第一个property用$.CustomerNames.Update路径,却命名为CREATE_PAYLOAD;第二个property用$.CustomerNames.Create路径,却命名为UPDATE_PAYLOAD。属性名和对应的数据路径完全不匹配,导致后续判断逻辑用错了目标数据。数组存在性判断逻辑错误
使用boolean(get-property('xxx'))判断JSON数组是否存在不可靠:当数组不存在或为空时,json-eval返回空字符串,而WSO2中boolean("")会被解析为true,无法准确区分“存在且有数据”和“不存在/空”的场景。正确做法是直接用json-eval的exists()函数判断路径是否存在,再结合size()函数判断数组是否有内容。Match Mediator使用冗余
boolean(...)已经返回布尔值,不需要再用match regex="true"去匹配,直接基于source的布尔结果判断即可,或者保留match但简化逻辑。
修正后的配置
可以直接去掉提前定义的属性,在条件中直接判断路径,避免属性名混淆:
<conditionalRouter continueAfter="true"> <conditionalRoute asynchronous="true" breakRoute="false"> <condition> <source>json-eval(exists($.CustomerNames.Create) and size($.CustomerNames.Create) > 0)</source> <match regex="true"/> </condition> <target sequence="CREATE_CUSTOMER"/> </conditionalRoute> <conditionalRoute asynchronous="true" breakRoute="false"> <condition> <source>json-eval(exists($.CustomerNames.Update) and size($.CustomerNames.Update) > 0)</source> <match regex="true"/> </condition> <target sequence="UPDATE_CUSTOMER"/> </conditionalRoute> </conditionalRouter>
如果需要兼容空数组也触发的场景,去掉size(...) > 0的判断即可。
内容的提问来源于stack exchange,提问作者Ruby

