Spring 同步 REST 调用的集成出站网关方式
Spring Integration Outbound Gate way for Synchronous REST Calls
以前我能够使用 Spring 集成开发一个小框架,开发人员可以在其中指定 URL、HTTP 方法和请求主体并调用任何外部 REST API。
这是我的 Spring 集成
的配置
<int:channel id='reply.channel'>
<int:queue capacity='10' />
</int:channel>
<int:channel id='request.channel'/>
<int:channel id='outbound.Channel'/>
<int:gateway id="outboundGateway"
service-interface="com.bst.pm.PostGateway"
default-request-channel="outbound.Channel">
</int:gateway>
<int:object-to-json-transformer input-channel="outbound.Channel" output-channel="request.channel"/>
<int-http:outbound-gateway id="outbound.gateway"
request-channel="request.channel" url-expression="headers.bstUrl"
http-method-expression="headers.bstHttpMethod" expected-response-type-expression="headers.bstExpectedResponseType"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel"
mapped-request-headers="bst*, HTTP_REQUEST_HEADERS">
</int-http:outbound-gateway>
然后开发人员可以使用上述基础结构调用外部 rest API 调用,如下所示
@Autowired @Qualifier("reply.channel") PollableChannel receivedChannel;
@Autowired @Qualifier("request.channel") MessageChannel getRequestChannel;
@Autowired @Qualifier("outbound.Channel") MessageChannel httpOutboundGateway;
Post post = new Post();
post.setTitle("Spring INtegration Test");
post.setBody("This is a sample request body to test Spring Integration HTTP Outbound gateway");
post.setUserId(Long.valueOf(1));
Message<?> message = MessageBuilder.withPayload(post)
.setHeader("bstUrl", "https://jsonplaceholder.typicode.com/posts")
.setHeader("bstHttpMethod", "POST")
.setHeader("bstExpectedResponseType", "com.bst.pages.crm.web.Post")
.build();
httpOutboundGateway.send(message);
Message<?> receivedMsg = receivedChannel.receive();
Post post = (Post) receivedMsg.getPayload();
System.out.println("############## ServerMsg ##############");
System.out.println(o);
System.out.println("############## Done! ##############");
在这里,我想通过此集成基础结构使所有 REST 调用同步。但是我已经使用 QUEUE 通道作为 http:outbound-gateway 的回复通道。因此,根据我的理解,错误的发件人可能会收到回复,因为任何人都可以汇集消息的频道。
我们如何确保正确的发件人总是会收到正确的回复?
谢谢,
凯斯
你是对的。如果真的有一个全局回复通道和多个并发进程,您最终可能会遇到工作窃取的情况。
要解决您的问题,您需要摆脱 HTTP 网关上的 reply-channel
,而只依赖消息网关填充的 replyChannel
header。但是,您的网关方法实际上应该是 request-reply 签名:它必须 return Object.
在参考手册中查看有关 replyChannel
header 的更多信息:https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#gateway
以前我能够使用 Spring 集成开发一个小框架,开发人员可以在其中指定 URL、HTTP 方法和请求主体并调用任何外部 REST API。
这是我的 Spring 集成
的配置<int:channel id='reply.channel'>
<int:queue capacity='10' />
</int:channel>
<int:channel id='request.channel'/>
<int:channel id='outbound.Channel'/>
<int:gateway id="outboundGateway"
service-interface="com.bst.pm.PostGateway"
default-request-channel="outbound.Channel">
</int:gateway>
<int:object-to-json-transformer input-channel="outbound.Channel" output-channel="request.channel"/>
<int-http:outbound-gateway id="outbound.gateway"
request-channel="request.channel" url-expression="headers.bstUrl"
http-method-expression="headers.bstHttpMethod" expected-response-type-expression="headers.bstExpectedResponseType"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel"
mapped-request-headers="bst*, HTTP_REQUEST_HEADERS">
</int-http:outbound-gateway>
然后开发人员可以使用上述基础结构调用外部 rest API 调用,如下所示
@Autowired @Qualifier("reply.channel") PollableChannel receivedChannel;
@Autowired @Qualifier("request.channel") MessageChannel getRequestChannel;
@Autowired @Qualifier("outbound.Channel") MessageChannel httpOutboundGateway;
Post post = new Post();
post.setTitle("Spring INtegration Test");
post.setBody("This is a sample request body to test Spring Integration HTTP Outbound gateway");
post.setUserId(Long.valueOf(1));
Message<?> message = MessageBuilder.withPayload(post)
.setHeader("bstUrl", "https://jsonplaceholder.typicode.com/posts")
.setHeader("bstHttpMethod", "POST")
.setHeader("bstExpectedResponseType", "com.bst.pages.crm.web.Post")
.build();
httpOutboundGateway.send(message);
Message<?> receivedMsg = receivedChannel.receive();
Post post = (Post) receivedMsg.getPayload();
System.out.println("############## ServerMsg ##############");
System.out.println(o);
System.out.println("############## Done! ##############");
在这里,我想通过此集成基础结构使所有 REST 调用同步。但是我已经使用 QUEUE 通道作为 http:outbound-gateway 的回复通道。因此,根据我的理解,错误的发件人可能会收到回复,因为任何人都可以汇集消息的频道。
我们如何确保正确的发件人总是会收到正确的回复?
谢谢, 凯斯
你是对的。如果真的有一个全局回复通道和多个并发进程,您最终可能会遇到工作窃取的情况。
要解决您的问题,您需要摆脱 HTTP 网关上的 reply-channel
,而只依赖消息网关填充的 replyChannel
header。但是,您的网关方法实际上应该是 request-reply 签名:它必须 return Object.
在参考手册中查看有关 replyChannel
header 的更多信息:https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#gateway