Spring integration spring集成:如何从WebFlux集成流创建spring反应堆通量?
在artem bilan中,未来将有可能使用webflux集成 自撰写评论以来,WebFlux集成就一直在进行。我尝试了以下方法,通过将MVC版本的Spring integration spring集成:如何从WebFlux集成流创建spring反应堆通量?,spring-integration,spring-webflux,Spring Integration,Spring Webflux,在artem bilan中,未来将有可能使用webflux集成 自撰写评论以来,WebFlux集成就一直在进行。我尝试了以下方法,通过将MVC版本的http.inboundChannelAdapter和@GetRequest处理程序替换为WebFlux.inboundChannelAdapter和WebFlux.inboundGateway,将基于MVC的http->flux集成复制为基于WebFlux的集成: @SpringBootApplication public class Webflu
http.inboundChannelAdapter
和@GetRequest
处理程序替换为WebFlux.inboundChannelAdapter
和WebFlux.inboundGateway
,将基于MVC的http->flux集成复制为基于WebFlux的集成:
@SpringBootApplication
public class WebfluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebfluxApplication.class, args);
}
@Bean
public Publisher<Message<String>> reactiveSource() {
return IntegrationFlows.
from(WebFlux.inboundChannelAdapter("/message/{id}")
.requestMapping(r -> r
.methods(HttpMethod.POST)
)
.payloadExpression("#pathVariables.id")
)
.log()
.channel(MessageChannels.flux())
.toReactivePublisher();
}
@Bean
public IntegrationFlow eventMessages() {
return IntegrationFlows
.from(WebFlux.inboundGateway("/events")
.requestMapping(m -> m.produces(MediaType.TEXT_EVENT_STREAM_VALUE)))
.handle((p, h) -> reactiveSource())
.get();
}
假出版商
.handle((p, h) -> Flux.just("foo", "bar"))
我收到了来自SSE的回复
curl localhost:8080/events
跟踪日志显示映射了reactiveSource()
POST处理程序,并且调用了webfluxinbundendpoint.handle
方法:
2018-05-05 16:50:58.788 INFO 6552 --- [ main] xIntegrationRequestMappingHandlerMapping : Mapped "{[/message/{id}],methods=[POST]}" onto public abstract reactor.core.publisher.Mono<java.lang.Void> org.springframework.web.server.WebHandler.handle(org.springframework.web.server.ServerWebExchange)
2018-05-05 16:50:58.789 INFO 6552 --- [ main] xIntegrationRequestMappingHandlerMapping : Mapped "{[/events],methods=[GET || POST],produces=[text/event-stream]}" onto public abstract reactor.core.publisher.Mono<java.lang.Void> org.springframework.web.server.WebHandler.handle(org.springframework.web.server.ServerWebExchange)
2018-05-05 16:50:59.191 INFO 6552 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext : Started HttpServer on /0:0:0:0:0:0:0:0:8080
2018-05-05 16:50:59.192 INFO 6552 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2018-05-05 16:50:59.196 INFO 6552 --- [ main] d.e.sample.webflux.WebfluxApplication : Started WebfluxApplication in 2.608 seconds (JVM running for 3.419)
2018-05-05 16:51:06.918 DEBUG 6552 --- [ctor-http-nio-2] o.s.web.reactive.DispatcherHandler : Processing POST request for [http://localhost:8080/message/4]
2018-05-05 16:51:06.932 DEBUG 6552 --- [ctor-http-nio-2] s.w.r.r.m.a.RequestMappingHandlerMapping : Looking up handler method for path /message/4
2018-05-05 16:51:06.933 DEBUG 6552 --- [ctor-http-nio-2] s.w.r.r.m.a.RequestMappingHandlerMapping : Did not find handler method for [/message/4]
2018-05-05 16:51:06.967 TRACE 6552 --- [ctor-http-nio-2] o.s.w.r.r.method.InvocableHandlerMethod : Invoking 'org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle' with arguments [org.springframework.web.server.adapter.DefaultServerWebExchange@775cdb20]
2018-05-05 16:51:06.967 TRACE 6552 --- [ctor-http-nio-2] o.s.w.r.r.method.InvocableHandlerMethod : Method [org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle] returned [MonoDefer]
2018-05-05 16:51:06.967 DEBUG 6552 --- [ctor-http-nio-2] o.s.w.r.r.method.InvocableHandlerMethod : Response fully handled in controller method
2018-05-05 16:51:11.363 DEBUG 6552 --- [ctor-http-nio-3] o.s.web.reactive.DispatcherHandler : Processing POST request for [http://localhost:8080/message/4]
2018-05-05 16:51:11.363 DEBUG 6552 --- [ctor-http-nio-3] s.w.r.r.m.a.RequestMappingHandlerMapping : Looking up handler method for path /message/4
2018-05-05 16:51:11.363 DEBUG 6552 --- [ctor-http-nio-3] s.w.r.r.m.a.RequestMappingHandlerMapping : Did not find handler method for [/message/4]
2018-05-05 16:51:11.364 TRACE 6552 --- [ctor-http-nio-3] o.s.w.r.r.method.InvocableHandlerMethod : Invoking 'org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle' with arguments [org.springframework.web.server.adapter.DefaultServerWebExchange@71f648a3]
2018-05-05 16:51:11.364 TRACE 6552 --- [ctor-http-nio-3] o.s.w.r.r.method.InvocableHandlerMethod : Method [org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle] returned [MonoDefer]
2018-05-05 16:51:11.364 DEBUG 6552 --- [ctor-http-nio-3] o.s.w.r.r.method.InvocableHandlerMethod : Response fully handled in controller method
2018-05-05 16:50:58.788 INFO 6552-[main]xintegrationRequestMappingHandler映射:将“{[/message/{id}],methods=[POST]}”映射到公共抽象reactor.core.publisher.Mono org.springframework.web.server.WebHandler.handler(org.springframework.web.server.ServerWebExchange)
2018-05-05 16:50:58.789 INFO 6552-[main]xIntegrationRequestMappingHandlerMapping:将“{[/events],methods=[GET | | POST],products=[text/event stream]}”映射到公共抽象reactor.core.publisher.Mono org.springframework.web.server.WebHandler.handler(org.springframework.web.server.ServerWebExchange)
2018-05-05 16:50:59.191信息6552---[ctor-http-nio-1]r.ipc.netty.tcp.BlockingNettyContext:在/0:0:0:0:0:8080上启动了HttpServer
2018-05-05 16:50:59.192信息6552---[main]o.s.b.web.embedded.netty.NettyWebServer:netty在端口上启动:8080
2018-05-05 16:50:59.196信息6552---[main]d.e.sample.webflux.webflux应用程序:在2.608秒内启动webflux应用程序(JVM运行3.419)
2018-05-05 16:51:06.918调试6552---[ctor-http-nio-2]o.s.web.reactive.DispatcherHandler:正在处理[http://localhost:8080/message/4]
2018-05-05 16:51:06.932调试6552---[ctor-http-nio-2]s.w.r.r.m.a.RequestMappingHandlerMapping:查找路径/消息的处理程序方法/4
2018-05-05 16:51:06.933调试6552---[ctor-http-nio-2]s.w.r.r.m.a.RequestMappingHandlerMapping:未找到[/message/4]的处理程序方法
2018-05-05 16:51:06.967 TRACE 6552---[ctor-http-nio-2]o.s.w.r.r.method.InvocableHandlerMethod:使用参数[org.springframework.integration.webflux.inbound.webfluxinbundendpoint.handle]调用“org.springframework.web.server.adapter”。DefaultServerWebExchange@775cdb20]
2018-05-05 16:51:06.967 TRACE 6552---[ctor-http-nio-2]o.s.w.r.r.method.InvocableHandlerMethod:method[org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle]返回[Monoder]
2018-05-05 16:51:06.967调试6552---[ctor-http-nio-2]o.s.w.r.r.method.InvocableHandler方法:在控制器方法中完全处理响应
2018-05-05 16:51:11.363调试6552---[ctor-http-nio-3]o.s.web.reactive.DispatcherHandler:正在处理[http://localhost:8080/message/4]
2018-05-05 16:51:11.363调试6552---[ctor-http-nio-3]s.w.r.r.m.a.RequestMappingHandlerMapping:查找路径/消息的处理程序方法/4
2018-05-05 16:51:11.363调试6552---[ctor-http-nio-3]s.w.r.r.m.a.RequestMappingHandlerMapping:未找到[/message/4]的处理程序方法
2018-05-05 16:51:11.364 TRACE 6552---[ctor-http-nio-3]o.s.w.r.r.method.InvocableHandlerMethod:使用参数[org.springframework.integration.webflux.inbound.webfluxinbundendpoint.handle]调用“org.springframework.web.server.adapter”。DefaultServerWebExchange@71f648a3]
2018-05-05 16:51:11.364 TRACE 6552---[ctor-http-nio-3]o.s.w.r.r.method.InvocableHandlerMethod:method[org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle]返回[MonoDefer]
2018-05-05 16:51:11.364调试6552---[ctor-http-nio-3]o.s.w.r.r.method.InvocableHandler方法:在控制器方法中完全处理响应
这是为什么?原因似乎是WebFluxInboundEndpoint在
doHandle()
行中停止处理没有正文的POST请求
.map(body -> new HttpEntity<>(...))
有了这样一个请求,我的日志将按预期包含传入的GenericMessage,/events资源开始生成SSE
2018-05-05 17:25:24.777 TRACE 40436 --- [ctor-http-nio-8] o.s.w.r.r.method.InvocableHandlerMethod : Method [org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle] returned [MonoDefer]
2018-05-05 17:25:24.777 DEBUG 40436 --- [ctor-http-nio-8] o.s.w.r.r.method.InvocableHandlerMethod : Response fully handled in controller method
2018-05-05 17:25:24.778 INFO 40436 --- [ctor-http-nio-8] o.s.integration.handler.LoggingHandler : GenericMessage [payload=4, headers={http_requestMethod=POST, Accept=*/*, User-Agent=curl/7.49.1, http_requestUrl=http://localhost:8080/message/4, Host=localhost:8080, id=9a09294d-280a-af3b-0894-23597cf1cb5f, Content-Length=1, contentType=application/x-www-form-urlencoded, timestamp=1525533924778}]
在编辑过程中,我尝试分配stackoverflow-spring集成webflux标记,但这还不存在。也许有足够声誉的人可以创建它。如果您这样做,它是如何工作的:
.habdle((p,h)->Flux.from(reactiveSource())
?不幸的是,我得到了相同的结果:reactiveSource()流中没有日志输出,/events资源上没有输出。我添加了跟踪日志,这表明调试日志有误导性:Webflux入站终结点实际上会被调用。当帖子没有正文时,WebFluxInboundEndpoint中的处理似乎会停止。这是一个很好的捕获!不过你可以接受自己的答案。我想你可以提出一个JIRA的问题,我们将修改如何在那里做的情况下空的尸体。不过你的SSE样品很棒。也许你不介意把它还给SI样本?好主意。不过,这个例子会使用带有body的帖子,可能会提到这个问题。顺便说一句,你能创建一个spring integration webflux StackOverflow标签吗(需要1500个声誉)?这样一个细粒度的标签是没有理由的-普通的spring integration
就足够了。我监视他们所有人。感谢您对吉拉和考虑的贡献!
private Mono<Void> doHandle(ServerWebExchange exchange) {
return extractRequestBody(exchange)
.doOnSubscribe(s -> this.activeCount.incrementAndGet())
.map(body -> new HttpEntity<>(body, exchange.getRequest().getHeaders()))
.map(entity -> buildMessage(entity, exchange))
.flatMap(requestMessage -> {
if (this.expectReply) {
return sendAndReceiveMessageReactive(requestMessage)
.flatMap(replyMessage -> populateResponse(exchange, replyMessage));
}
else {
send(requestMessage);
return setStatusCode(exchange);
}
})
.doOnTerminate(this.activeCount::decrementAndGet);
}
curl -d ' http://localhost:8080/message/4
2018-05-05 17:25:24.777 TRACE 40436 --- [ctor-http-nio-8] o.s.w.r.r.method.InvocableHandlerMethod : Method [org.springframework.integration.webflux.inbound.WebFluxInboundEndpoint.handle] returned [MonoDefer]
2018-05-05 17:25:24.777 DEBUG 40436 --- [ctor-http-nio-8] o.s.w.r.r.method.InvocableHandlerMethod : Response fully handled in controller method
2018-05-05 17:25:24.778 INFO 40436 --- [ctor-http-nio-8] o.s.integration.handler.LoggingHandler : GenericMessage [payload=4, headers={http_requestMethod=POST, Accept=*/*, User-Agent=curl/7.49.1, http_requestUrl=http://localhost:8080/message/4, Host=localhost:8080, id=9a09294d-280a-af3b-0894-23597cf1cb5f, Content-Length=1, contentType=application/x-www-form-urlencoded, timestamp=1525533924778}]