webflux-Only one connection receive subscriber allowed問題定位

使用spring-boot-2.1.1(對應spring-framwork-5.1.3)編寫webflux代碼時出現以下問題:Only one connection receive subscriber allowed. 代碼以下:html

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

請求返回以下(使用x-www-form-urlencoded): 請求java

使用form-data不會報錯react

從異常看,就是一個生產者被再次消費。 看起來webflux處理方式跟mvc有點不一樣。查看官方文檔 image.pngweb

將代碼修改成:spring

@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");
}

問題解決。mvc

問題緣由追查

跟蹤代碼:app

  1. 打開全局調試Hooks.onOperatorDebug();
  2. createExchange的時候調用了ReactorServerHttpRequest#getBody image.png
  3. 而後被消費,map裏面的代碼被惰性執行。 image.png
  4. 解決調用框架參數時又調用了getBody。再次消費的話,必然報錯。 image.png

結語

spring-framework-5.2.8就沒這個困擾,異常中直接告訴你In a WebFlux application, form data is accessed via ServerWebExchange.getFormData(). image.png框架

相關文章
相關標籤/搜索