[英]Spring REST Request Response with Spring Cloud Stream
I am trying to connect a rest endpoint Request/Response with Spring cloud stream using Spring integration gateway. 我正在尝试使用Spring集成网关将其余端点的请求/响应与Spring云流连接。 The below code works for the first rest call, but subsequent calls do not work.
以下代码适用于第一个rest调用,但后续调用不起作用。 I understand that spring cloud stream is for messaging/async operations.
我知道Spring Cloud Stream是用于消息传递/异步操作的。 But this is a practical scenario where in which you need a request/response sync.
但这是一种实际情况,其中您需要请求/响应同步。
SpringBootApplication SpringBoot应用程序
package com.example.restgateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.dsl.HeaderEnricherSpec;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@EnableBinding({RestGatewayApplication.GatewayChannels.class})
@SpringBootApplication
public class RestGatewayApplication {
interface GatewayChannels {
String TO_UPPERCASE_REPLY = "to-uppercase-reply";
String TO_UPPERCASE_REQUEST = "to-uppercase-request";
@Input(TO_UPPERCASE_REPLY)
SubscribableChannel toUppercaseReply();
@Output(TO_UPPERCASE_REQUEST)
MessageChannel toUppercaseRequest();
}
@MessagingGateway
public interface StreamGateway {
@Gateway(requestChannel = ENRICH, replyChannel = GatewayChannels.TO_UPPERCASE_REPLY)
String process(String payload);
}
private static final String ENRICH = "enrich";
public static void main(String[] args) {
SpringApplication.run(RestGatewayApplication.class, args);
}
@Bean
public IntegrationFlow headerEnricherFlow() {
return IntegrationFlows.from(ENRICH).enrichHeaders(HeaderEnricherSpec::headerChannelsToString)
.channel(GatewayChannels.TO_UPPERCASE_REQUEST).get();
}
@RestController
public class UppercaseController {
@Autowired
StreamGateway gateway;
@GetMapping(value = "/uppercase/{string}",
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<String> getUser(@PathVariable("string") String string) {
return new ResponseEntity<String>(gateway.process(string), HttpStatus.OK);
}
}
@StreamListener(GatewayChannels.TO_UPPERCASE_REQUEST)
@SendTo(GatewayChannels.TO_UPPERCASE_REPLY)
public Message<?> process(Message<String> request) {
return MessageBuilder.withPayload(request.getPayload().toUpperCase())
.copyHeaders(request.getHeaders()).build();
}
}
application.yml application.yml
spring:
cloud:
stream:
bindings:
to-uppercase-request:
destination: to-uppercase-request
group: stream-to-uppercase-request
producer:
required-groups: stream-to-uppercase-request
to-uppercase-reply:
destination: to-uppercase-reply
group: gateway-to-uppercase-reply
producer:
required-groups: gateway-to-uppercase-reply
kafka:
binder:
brokers:
- 192.168.34.210:9092
default-binder: kafka
server:
port: 8080
It's not clear what you are trying to do; 目前尚不清楚您要做什么。 the IntegrationFlow is sending a message directly to the input channel, bypassing the destination topic;
IntegrationFlow正在绕过目标主题直接向输入通道发送消息; the reply (alternately) goes out via the topic and the
replyChannel
header (required by the gateway will be lost since it's not serializable). 答复(或者)通过主题和
replyChannel
标replyChannel
(网关要求的消息将丢失,因为它不可序列化)。
It will work alternately because you have 2 subscribers on the reply channel - the gateway and the binding. 因为您在回复通道上有2个订阅者(网关和绑定),所以它将交替工作。 By default, when a channel has 2 subscribers, messages are distributed in round-robin fashion.
默认情况下,当一个频道有2个订阅者时,消息以循环方式分发。 One message will go to the gateway, the next to the binding, etc, etc.
一条消息将发送到网关,另一条消息将发送到绑定,等等,依此类推。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.