WSO2 MI记录JSON响应时触发JsonStreamBuilder处理application/json异常
WSO2 MI 记录JSON响应时JsonStreamBuilder错误排查与修复
在WSO2 Micro Integrator中尝试记录目标端点返回的JSON响应时,出现以下错误日志:
[2025-04-17 17:26:04,349] ERROR {JsonStreamBuilder} - Error occurred while processing document for application/json
对应的API inSequence代码如下:
<call> <endpoint key="todos-server"/> </call> <log level="custom"> <property name="ContentType" expression="get-property('axis2', 'ContentType')"/> <property name="RawResponse" expression="$body"/> </log> <property name="CHARACTER_SET_ENCODING" value="UTF-8" scope="axis2" type="STRING"/> <property name="messageType" value="application/json" scope="axis2" type="STRING"/> <log level="custom"> <property name="JsonResponse" expression="json-eval($)"/> </log> <respond/>
直接用Postman或浏览器测试该API时功能正常,但日志中持续出现上述错误。
错误原因
- WSO2 MI的消息流是一次性消耗的,调用端点后使用
$body记录原始响应时,已经将流数据读取完毕。后续设置messageType并尝试用json-eval($)解析JSON时,流已为空,导致JsonStreamBuilder处理失败。 - 若目标端点返回的Content-Type已是
application/json,重复设置messageType会触发不必要的重新解析操作,加剧流耗尽的问题。
修复方案
方案1:调整日志顺序,避免提前消耗流
将消息类型设置步骤移到日志操作之前,直接使用json-eval($)记录JSON响应,确保流数据不被提前消耗:
<call> <endpoint key="todos-server"/> </call> <!-- 先设置消息编码和类型,确保JSON解析基于正确格式 --> <property name="CHARACTER_SET_ENCODING" value="UTF-8" scope="axis2" type="STRING"/> <property name="messageType" value="application/json" scope="axis2" type="STRING"/> <log level="custom"> <property name="ContentType" expression="get-property('axis2', 'ContentType')"/> <property name="JsonResponse" expression="json-eval($)"/> </log> <respond/>
方案2:克隆消息记录原始响应(如需保留原始流日志)
如果必须记录原始响应流,使用<clone> mediator克隆消息,在独立序列中处理日志,不影响主流程的流数据:
<call> <endpoint key="todos-server"/> </call> <clone> <target> <sequence> <!-- 在克隆序列中记录原始响应,不消耗主流程的流 --> <log level="custom"> <property name="ContentType" expression="get-property('axis2', 'ContentType')"/> <property name="RawResponse" expression="$body"/> </log> </sequence> </target> </clone> <property name="CHARACTER_SET_ENCODING" value="UTF-8" scope="axis2" type="STRING"/> <property name="messageType" value="application/json" scope="axis2" type="STRING"/> <log level="custom"> <property name="JsonResponse" expression="json-eval($)"/> </log> <respond/>
补充说明
直接用Postman测试正常的原因是,最终的<respond/>操作依赖的是调用端点后已构建的响应数据,而中间日志操作消耗流导致的JSON解析错误仅在日志环节触发,不影响最终响应返回。
内容的提问来源于stack exchange,提问作者ABDLEHADI EL BCIR




