WSO2 EI执行URL编码调用后JSON请求解析异常求助
问题背景
在WSO2 EI中配置的序列先执行application/x-www-form-urlencoded格式的REST调用,再执行JSON格式API调用时,第三方服务抛出JSON解析错误:
JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
跳过第一个URL编码调用则无此错误,修改messageType或重置请求头无效。
问题根源
第一个URL编码调用后,消息上下文(Message Context)中残留了ASCII控制字符(Code 31,Unit Separator)。这些字符被带入到后续JSON请求的payload中,而第三方JSON解析器不允许此类控制字符存在于JSON内容中。仅修改请求头或messageType无法清除这些残留的二进制/控制字符。
解决方案
方案1:彻底重置消息上下文(推荐)
在第二个JSON调用前,先清除之前调用残留的消息内容和属性,避免污染后续请求:
<!-- 清除之前的消息内容和核心属性 --> <property name="MESSAGE" scope="default" action="remove"/> <property name="PAYLOAD" scope="default" action="remove"/> <property name="axis2.REQUEST_HEADERS" scope="axis2" action="remove"/> <!-- 明确设置JSON相关的传输属性 --> <property name="messageType" scope="axis2" type="STRING" value="application/json"/> <property name="ContentType" scope="transport" type="STRING" value="application/json"/> <!-- 重新构建JSON Payload --> <payloadFactory media-type="json"> <format>$1</format> <args> <arg evaluator="xml" expression="get-property('REQUEST')" xmlns:ns="http://org.apache.synapse/xsd"/> </args> </payloadFactory>
方案2:过滤REQUEST属性中的控制字符
如果必须保留REQUEST属性的内容,可通过脚本过滤掉非法控制字符:
<script language="js"> var rawPayload = mc.getProperty('REQUEST'); // 移除所有ASCII控制字符,仅保留合法空白符(\r、\n、\t) var cleanedPayload = rawPayload.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ''); mc.setProperty('REQUEST', cleanedPayload); </script> <!-- 执行原JSON Payload构建逻辑 --> <payloadFactory media-type="json"> <format>$1</format> <args> <arg evaluator="xml" expression="get-property('REQUEST')" xmlns:ns="http://org.apache.synapse/xsd"/> </args> </payloadFactory>
方案3:清理第一个调用后的axis2属性
第一个调用设置的DISABLE_CHUNKING等axis2属性可能影响后续请求的编码处理,调用完成后立即清理:
<!-- 第一个URL编码调用完成后添加以下配置 --> <property name="DISABLE_CHUNKING" scope="axis2" action="remove"/> <property name="messageType" scope="axis2" action="remove"/> <property name="ContentType" scope="transport" action="remove"/>
验证方法
- 部署修改后的序列
- 发起测试请求,检查第三方服务是否仍报错
- 若问题未解决,启用WSO2 EI的Message Tracer功能,查看第二个请求的原始payload,确认控制字符是否已被清除
内容的提问来源于stack exchange,提问作者user666

