WSO2 Integration Studio中Payload到达后端变为空的问题求助
问题现象
在WSO2 Integration Studio中开发的API,能够将XML格式的请求Payload成功转换为JSON格式(转换结果可在日志中查看),但当请求转发到后端服务时,后端接收的Payload却为null。
相关代码及日志
API代码
<?xml version="1.0" encoding="UTF-8"?> <api context="/props" name="props_api" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="POST"> <inSequence> <payloadFactory media-type="json" template-type="freemarker"> <format>{ "name": "${payload.root.user.name}", "description": "${payload.root.user.description}" }</format> <args> <arg evaluator="xml" expression="//root/user/name"/> <arg evaluator="xml" expression="//root/user/description"/> </args> </payloadFactory> <header name="Content-Type" scope="transport" value="application/json"/> <log level="full"/> <send> <endpoint> <address uri="http://127.0.0.1:8000/drinks/"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </address> </endpoint> </send> </inSequence> <outSequence> <send/> </outSequence> <faultSequence/> </resource> </api>
原始XML Payload
<root> <user> <name>s</name> <description>dd</description> </user> </root>
日志中显示的转换后JSON Payload
{ "name": "s", "description": "dd" }
后端错误日志
[2023-02-26 18:13:21,282] INFO {LogMediator} - {api:props_api} To: /props, MessageID: urn:uuid:e5b8eb0f-85d0-4150-a284-1292b6c902be, correlation_id: e5b8eb0f-85d0-4150-a284-1292b6c902be, Direction: request, Payload: { "name": "s", "description":"dd" } [2023-02-26 18:13:21,282] INFO {LogMediator} - {api:props_api} To: /props, MessageID: urn:uuid:e5b8eb0f-85d0-4150-a284-1292b6c902be, correlation_id: e5b8eb0f-85d0-4150-a284-1292b6c902be, Direction: request, Payload: { "name": "s", "description": "dd" } [2023-02-26 18:13:21,306] ERROR {TargetHandler} - HTTP protocol violation : Not a valid protocol version: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" For : 127.0.0.1:8000 org.apache.http.ProtocolException: Not
问题分析
从错误日志中的HTTP protocol violation异常可以看出,WSO2收到后端返回的是HTML内容(而非合法的HTTP响应),这大概率是因为端点URL不正确,导致请求发送到了不存在的路径,后端返回了404错误页面。这种情况下,后端可能根本没有正确接收请求,或者请求传递过程中出现异常,最终表现为后端接收Payload为null。
另外,也需要排除WSO2在转发请求时未正确传递Payload的可能,比如默认配置下POST请求的Payload传递机制存在问题。
解决方案
验证端点URL正确性
确认后端服务的实际部署路径,比如是否需要去掉URL末尾的斜杠(http://127.0.0.1:8000/drinks),或者路径是否与后端服务的路由配置匹配。可以直接用Postman调用后端URL,确认能正常接收JSON格式的POST请求。强制传递POST Payload
在sendmediator之前添加FORCE_POST_PAYLOAD属性,确保WSO2强制发送POST请求的Payload:<property name="FORCE_POST_PAYLOAD" value="true" scope="axis2"/>修改后的inSequence示例:
<inSequence> <payloadFactory media-type="json" template-type="freemarker"> <format>{ "name": "${payload.root.user.name}", "description": "${payload.root.user.description}" }</format> <args> <arg evaluator="xml" expression="//root/user/name"/> <arg evaluator="xml" expression="//root/user/description"/> </args> </payloadFactory> <header name="Content-Type" scope="transport" value="application/json"/> <property name="FORCE_POST_PAYLOAD" value="true" scope="axis2"/> <log level="full"/> <send> <endpoint> <address uri="http://127.0.0.1:8000/drinks/"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </address> </endpoint> </send> </inSequence>检查后端服务的JSON解析配置
确认后端服务已经配置了JSON请求的解析逻辑(比如Spring Boot中的@RequestBody、Python Flask中的request.get_json()),能够正确接收并解析application/json格式的Payload。启用Wire日志排查请求细节
在WSO2的log4j2.xml配置文件中添加Wire日志配置,查看发送到后端的完整HTTP请求,确认Payload是否被正确发送:<Logger name="org.apache.synapse.transport.http.wire" level="DEBUG"/>重启服务后,查看日志中Wire相关的输出,确认请求头和Payload是否符合预期。
内容的提问来源于stack exchange,提问作者Ajith Nirmal

