如何使用WSO2 EI Enrich Mediator移除Payload Factory中的JSON字段?
移除JSON Payload空字段时触发MalformedJsonException错误
我需要将包含多字段的Payload中非空字段单独发送给后端,尝试用Enrich Mediator移除空字段时出现了JSON格式错误。
现有Payload Factory配置
<payloadFactory media-type="json"> <format> { "_putupdateuser": { "BADLOGINS": $1, "EMAIL": "$2", "FRAMED_ROUTE": "$3" } } </format> <args> <arg evaluator="xml" expression="get-property('BADLOGINS')"/> <arg evaluator="xml" expression="get-property('EMAIL')"/> <arg evaluator="xml" expression="get-property('FRAMED_ROUTE')"/> </args> </payloadFactory>
现有Enrich Mediator配置
<enrich> <source clone="false" xpath="json-eval($._putupdateuser.FRAMED_ROUTE)"/> <target action="remove" type="body"/> </enrich>
报错信息
Caused by: com.google.gson.stream.MalformedJsonException: Unexpected value at line 3 column 32 path $._putupdateuser.BADLOGINS
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1568)
问题根源
- Payload Factory生成非法JSON:当属性值为空时,生成的JSON会出现类似
"BADLOGINS": ,的语法错误,直接触发Gson的解析异常。 - Enrich Mediator用法错误:该组件不是用来批量移除空字段的合适工具,当前配置会直接操作不合法的JSON结构,加剧格式问题。
解决办法
方案1:动态构建合法JSON(Payload Factory+XSL判断)
通过XSL条件判断,只添加非空字段,同时处理末尾逗号问题:
<payloadFactory media-type="json"> <format> { "_putupdateuser": { <xsl:if test="get-property('BADLOGINS') != ''">"BADLOGINS": $1<xsl:if test="get-property('EMAIL') != '' or get-property('FRAMED_ROUTE') != ''">,</xsl:if></xsl:if> <xsl:if test="get-property('EMAIL') != ''">"EMAIL": "$2"<xsl:if test="get-property('FRAMED_ROUTE') != ''">,</xsl:if></xsl:if> <xsl:if test="get-property('FRAMED_ROUTE') != ''">"FRAMED_ROUTE": "$3"</xsl:if> } } </format> <args> <arg evaluator="xml" expression="get-property('BADLOGINS')"/> <arg evaluator="xml" expression="get-property('EMAIL')"/> <arg evaluator="xml" expression="get-property('FRAMED_ROUTE')"/> </args> </payloadFactory>
方案2:用Script Mediator动态生成JSON(推荐)
用JavaScript逻辑更清晰地构建非空字段的JSON,避免格式错误:
<script language="js"> var updateUser = {}; // 处理BADLOGINS(根据实际类型转换,比如数字) var badLogins = mc.getProperty("BADLOGINS"); if (badLogins && badLogins.trim() !== "") { updateUser.BADLOGINS = parseInt(badLogins); } // 处理EMAIL var email = mc.getProperty("EMAIL"); if (email && email.trim() !== "") { updateUser.EMAIL = email; } // 处理FRAMED_ROUTE var framedRoute = mc.getProperty("FRAMED_ROUTE"); if (framedRoute && framedRoute.trim() !== "") { updateUser.FRAMED_ROUTE = framedRoute; } // 设置最终Payload mc.setPayloadJSON({ "_putupdateuser": updateUser }); </script>
方案3:修复Enrich Mediator用法(备选)
先将空值转为合法的null,再通过Enrich过滤掉null字段:
<!-- 先将空值替换为null,保证JSON合法 --> <payloadFactory media-type="json"> <format> { "_putupdateuser": { "BADLOGINS": $1, "EMAIL": "$2", "FRAMED_ROUTE": "$3" } } </format> <args> <arg evaluator="xml" expression="if(get-property('BADLOGINS') != '') then get-property('BADLOGINS') else 'null'"/> <arg evaluator="xml" expression="if(get-property('EMAIL') != '') then get-property('EMAIL') else 'null'"/> <arg evaluator="xml" expression="if(get-property('FRAMED_ROUTE') != '') then get-property('FRAMED_ROUTE') else 'null'"/> </args> </payloadFactory> <!-- 过滤掉值为null的字段 --> <enrich> <source clone="false" xpath="json-eval($._putupdateuser[?(@ != null)])"/> <target action="replace" type="body"/> </enrich>
内容的提问来源于stack exchange,提问作者Oussama Nairi
相关产品推荐
相关产品推荐

