API Manager自定义中介策略:调用端点存储响应问题求助
解决方案
要实现调用外部端点并将响应存入Header,同时保留原请求继续调用后端,你需要用Call Mediator的阻塞模式同步获取外部响应,提取所需字段存入Header后恢复原请求上下文。你的原序列仅设置To头但未发起实际调用,也未处理响应存储和原请求恢复,因此无法达到预期效果。
以下是修正后的中介序列:
<?xml version="1.0" encoding="UTF-8"?> <sequence name="UserToken" trace="disable" xmlns="http://ws.apache.org/ns/synapse"> <log> <property name="[User Token]" value="进入序列"/> </log> <!-- 1. 保存原请求的Payload和传输头,避免被外部调用覆盖 --> <property name="ORIGINAL_PAYLOAD" expression="$body" scope="default"/> <property name="ORIGINAL_TRANSPORT_HEADERS" expression="$trp:*" scope="default"/> <!-- 2. 清理无关属性,构造OAuth调用的基础请求 --> <property action="remove" name="REST_URL_POSTFIX" scope="axis2"/> <property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/> <!-- 如果OAuth端点需要客户端认证,添加Basic Auth头,示例: <header name="Authorization" scope="transport" value="Base64编码的客户端ID:密钥"/> --> <payloadFactory media-type="json"> <format>{}</format> <args/> </payloadFactory> <!-- 3. 阻塞模式调用OAuth端点,同步获取响应 --> <call blocking="true"> <endpoint> <address uri="https://22.33.444.55:8080/oauth/token?grant_type=client_credentials"/> </endpoint> </call> <!-- 4. 从OAuth响应提取令牌,存入自定义传输头 --> <property name="OAUTH_ACCESS_TOKEN" expression="json-eval($.access_token)" scope="default"/> <header name="X-User-Token" scope="transport" expression="$ctx:OAUTH_ACCESS_TOKEN"/> <!-- 5. 恢复原请求的Payload和传输头,保证后续调用原后端正常 --> <property name="TRANSPORT_HEADERS" expression="$ctx:ORIGINAL_TRANSPORT_HEADERS" scope="axis2"/> <payloadFactory media-type="json"> <format>$1</format> <args> <arg evaluator="xml" expression="$ctx:ORIGINAL_PAYLOAD"/> </args> </payloadFactory> <log> <property name="[User Token]" value="令牌获取完成,已存入X-User-Token头"/> <property name="X-User-Token" expression="$trp:X-User-Token"/> </log> </sequence>
关键细节说明:
blocking="true"的必要性:Call Mediator默认是非阻塞模式,会直接跳过等待响应的步骤,必须开启阻塞模式才能同步获取OAuth端点的响应内容。- 原请求上下文的保存与恢复:调用外部端点后,消息上下文会被替换为外部响应,因此必须提前保存原请求的Payload和传输头,处理完OAuth逻辑后再恢复,确保原请求能正常发送到后端。
- 响应字段提取:示例用
json-eval($.access_token)从JSON响应中提取令牌,若你的OAuth端点返回XML,改用对应的XPath表达式即可。 - 客户端认证补充:如果OAuth端点要求客户端ID和密钥进行Basic认证,需要手动添加
Authorization头,将客户端ID:密钥做Base64编码后填入值字段。
原序列无效的核心原因:
- 仅设置
To头不会自动触发请求,必须通过Call/Send Mediator主动发起调用。 - Send Mediator是单向调用,不会返回响应,无法满足获取OAuth响应并存入Header的需求。
- 未保存原请求上下文,调用外部端点后原请求内容丢失,后续无法正常调用原后端。
内容的提问来源于stack exchange,提问作者Saranya Karuppasamy
相关产品推荐
相关产品推荐

