使用spring-boot-2.1.1(对应spring-framwork-5.1.3)编写webflux代码时出现如下问题:Only one connection receive subscriber allowed.
代码如下:
@RequestMapping("/xmldata")
public Mono<String> xmldata(@RequestBody String xmldata) {
log.info(xmldata);
return Mono.just("success");
}
请求返回如下(使用x-www-form-urlencoded
):
使用
form-data
不会报错
从异常看,就是一个生产者被再次消费。
看起来webflux处理方式跟mvc有点不同。查看官方文档
将代码修改为:
@RequestMapping("/xmldata")
public Mono<String> xmldata(ServerWebExchange exchange) {
Mono<MultiValueMap<String, String>> formData = exchange.getFormData();
formData.subscribe(data -> {
log.info(data.getFirst("xmldata"));
});
return Mono.just("success");
}
问题解决。
问题原因追查
跟踪代码:
- 打开全局调试
Hooks.onOperatorDebug();
-
createExchange
的时候调用了ReactorServerHttpRequest#getBody
image.png -
然后被消费,map里面的代码被惰性执行。
image.png -
解决调用框架参数时又调用了getBody。再次消费的话,必然报错。
image.png
结语
spring-framework-5.2.8就没这个困扰,异常中直接告诉你In a WebFlux application, form data is accessed via ServerWebExchange.getFormData().
网友评论