webflux-Only one connection receive subscriber allowed问题定位

使用spring-boot-2.1.1(对应spring-framwork-5.1.3)编写webflux代码时出现如下问题:Only one connection receive subscriber allowed.
代码如下:

@RequestMapping("/xmldata")
public Mono xmldata(@RequestBody String xmldata) {
    log.info(xmldata);
    return Mono.just("success");
}

请求返回如下(使用x-www-form-urlencoded):

webflux-Only one connection receive subscriber allowed问题定位_第1张图片
请求

使用form-data不会报错

从异常看,就是一个生产者被再次消费。
看起来webflux处理方式跟mvc有点不同。查看官方文档

webflux-Only one connection receive subscriber allowed问题定位_第2张图片
image.png

将代码修改为:

@RequestMapping("/xmldata")
public Mono xmldata(ServerWebExchange exchange) {
    Mono> formData = exchange.getFormData();
    formData.subscribe(data -> {
        log.info(data.getFirst("xmldata"));
    });
    return Mono.just("success");
}

问题解决。

问题原因追查

跟踪代码:

  1. 打开全局调试Hooks.onOperatorDebug();
  2. createExchange的时候调用了ReactorServerHttpRequest#getBody
    webflux-Only one connection receive subscriber allowed问题定位_第3张图片
    image.png
  3. 然后被消费,map里面的代码被惰性执行。


    webflux-Only one connection receive subscriber allowed问题定位_第4张图片
    image.png
  4. 解决调用框架参数时又调用了getBody。再次消费的话,必然报错。


    webflux-Only one connection receive subscriber allowed问题定位_第5张图片
    image.png

结语

spring-framework-5.2.8就没这个困扰,异常中直接告诉你In a WebFlux application, form data is accessed via ServerWebExchange.getFormData().

image.png

你可能感兴趣的:(webflux-Only one connection receive subscriber allowed问题定位)