Spring Webflux中ServerRequest请求体为null如何正确提取请求体
问题根因
请求体读取失败是因为错误使用了WebFlux响应式API,违反了响应式流的执行规则:
- 手动调用
subscribe()消费请求体:WebFlux框架本身会统一管理请求生命周期内的流订阅,手动私自订阅会和框架的流调度冲突,要么读不到数据,要么触发流重复消费异常。 - 阻塞读取未就绪数据:
toProcessor().peek()是阻塞操作,执行时请求体的IO读取还没完成,拿到的必然是null,同时阻塞操作会占用WebFlux的事件循环线程,严重时会导致服务完全无法响应请求。
可行解决方案
必须把请求体读取逻辑整合到请求处理的完整响应式流中,由框架负责触发订阅,禁止手动订阅、阻塞读取。
修正后的handler方法代码如下:
public Mono<ServerResponse> test(ServerRequest serverRequest) { // 请求头在进入handler时已经完成解析,可以直接读取 System.out.println(serverRequest.headers()); return serverRequest.bodyToMono(String.class) // 流读取到完整请求体后执行打印逻辑 .doOnNext(requestBody -> System.out.println("请求体内容:" + requestBody)) // 请求体处理完成后返回响应 .then(ServerResponse.ok().bodyValue("ok")); }
另外你当前使用的curl命令存在JSON转义问题,很可能导致实际传输的请求体格式错误,建议调整为以下写法(类Unix环境通用):
curl -d '{"key1":"value1", "key2":"value2"}' \ -H "Content-Type: application/json" \ -X POST http://localhost:8080/myApi/test
注意:
ServerRequest暴露的请求体流只能被消费一次,如果需要多次使用请求体内容,请在第一次读取后将内容缓存到局部变量中复用,不要重复调用bodyToMono/bodyToFlux方法。
内容的提问来源于stack exchange,提问作者yjs
相关产品推荐
相关产品推荐

