WSO2 EI PayloadFactory转换时空字段被转为null而非空字符串
问题描述
WSO2 EI集成流程中,从DSS服务执行select查询获取数据,经PayloadFactory中介完成JSON载荷转换后转发至目标端点时,所有空字段被自动转换为null值传递,不符合预期的空字符串""输出要求。
- 异常输出示例
"department":null, "Selling_dealer__c":null
- 预期输出格式
"department":"", "Selling_dealer__c":""
已尝试参考官方文档及社区方案修改synapse.properties配置,未达到预期效果。
原有问题配置
<sequence name="LaravelConnectorSequence" xmlns="http://ws.apache.org/ns/synapse"> <payloadFactory media-type="json"> <format> { "screen_type": "opportunity", "vehicle_type__c": "", "description": "", "audio_file_name__c": "$1", "lead_type__c": "Phone", "request_type__c": "", "mobile__c": "$2", "leadsource": "Novum", "company__c": "N/A", "location__c": "$3", "department__c": "$4", "selling_dealer__c":"$5" } </format> <args> <arg evaluator="xml" expression="get-property('audioFileName')" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('mobile')" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('location')" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('department')" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('selling_dealer__c')" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> </args> </payloadFactory> <log level="custom"> <property expression="json-eval($)" name="=======Laravel Request====" xmlns:ns="http://org.apache.synapse/xsd"/> </log> <property expression="get-property('Novum-configs')" name="config" scope="axis2" type="OM" xmlns:ns="http://org.apache.synapse/xsd"/> <property expression="$axis2:config//*[local-name()='laravelToken']" name="Authorization" scope="transport" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/> <property expression="$axis2:config//*[local-name()='laravelURL']" name="uri.var.laravelapi" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/> <call> <endpoint> <http method="POST" uri-template="{uri.var.laravelapi}"/> </endpoint> </call> <log level="custom"> <property expression="json-eval($)" name="=======Laravel Response====" xmlns:ns="http://org.apache.synapse/xsd"/> </log> </sequence>
根因说明
PayloadFactory做占位符替换时,如果绑定的传入参数本身为null/空值,WSO2内置的JSON序列化器会优先识别null类型,直接覆盖format里预置的空字符串设置,最终输出null而非""。仅修改全局序列化配置时,如果传入参数本身是null类型,部分EI版本仍会输出null值。
可行解决方案
方案1:参数取值时做空值兜底(优先推荐)
该方案无需修改全局配置,不影响其他接口逻辑,仅需在参数传入PayloadFactory前做非空兜底,保证传入替换的参数值为空时返回空字符串即可。
可直接在PayloadFactory的arg表达式中增加空值判断,修改后的args配置如下:
<args> <arg evaluator="xml" expression="get-property('audioFileName') != '' ? get-property('audioFileName') : ''" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('mobile') != '' ? get-property('mobile') : ''" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('location') != '' ? get-property('location') : ''" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('department') != '' ? get-property('department') : ''" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> <arg evaluator="xml" expression="get-property('selling_dealer__c') != '' ? get-property('selling_dealer__c') : ''" literal="false" xmlns:ns="http://org.apache.synapse/xsd"/> </args>
也可以在PayloadFactory中介之前,提前对可能为空的属性统一赋值空字符串,示例配置:
<!-- 提前对空字段做兜底赋值 --> <property name="audioFileName" expression="get-property('audioFileName') != '' ? get-property('audioFileName') : ''" scope="default" type="STRING"/> <property name="mobile" expression="get-property('mobile') != '' ? get-property('mobile') : ''" scope="default" type="STRING"/> <property name="location" expression="get-property('location') != '' ? get-property('location') : ''" scope="default" type="STRING"/> <property name="department" expression="get-property('department') != '' ? get-property('department') : ''" scope="default" type="STRING"/> <property name="selling_dealer__c" expression="get-property('selling_dealer__c') != '' ? get-property('selling_dealer__c') : ''" scope="default" type="STRING"/>
方案2:修正全局JSON序列化配置(全局生效)
如果所有接口都要求空值输出为空字符串,可修正synapse.properties配置,之前配置未生效通常是漏配关键项。进入EI节点的conf/目录,修改synapse.properties文件,添加/更新以下配置项后重启服务:
# 关闭自动原始类型识别 synapse.commons.json.output.autoPrimitive = false # 开启null值转空字符串 synapse.commons.json.output.null.to.empty = true # 保留空元素 synapse.commons.json.preserve.empty.element = true
注意:该配置为节点全局配置,会影响该节点上所有集成接口的JSON序列化逻辑,修改后必须全量回归现有接口,避免出现非预期格式输出。
踩坑提示
不要尝试仅在PayloadFactory的format模板中将字段预置为"key":""实现空字符串输出,只要传入的替换参数为null,JSON序列化阶段就会覆盖预置的空字符串,最终输出null值。必须保证传入PayloadFactory的替换参数本身是非null的字符串类型,才能稳定输出空字符串。
内容的提问来源于stack exchange,提问作者Thamu

