Spring Webflux ServerResponse空白及未认证flatMap不执行问题排查
Spring Webflux RouterFunction 认证场景响应问题修复
原代码问题
@Bean public RouterFunction<ServerResponse> refresh() { return route(GET("/api/refresh"), (request) -> request.principal().or(Mono.empty()).flatMap((it) -> { System.out.println(it); return ServerResponse.ok().body(Mono.just(new FreshStatus(true)), FreshStatus.class); })); } record FreshStatus(boolean isFresh) {}
存在两个问题:
- 未认证时:
flatMap内代码完全不执行,响应状态码200但无内容 - 已认证时:
flatMap内代码正常执行(能打印Principal),但响应体空白,状态码仍为200
问题原因
- 未认证场景:
request.principal()本身就会返回Mono.empty(),调用.or(Mono.empty())后还是空Mono。而flatMap仅在上游Mono有值时才会执行逻辑,因此整个handler最终返回Mono.empty(),Spring Webflux会将其处理为200 OK的空响应。 - 已认证场景:原代码在
flatMap内构建ServerResponse,虽逻辑合法,但存在订阅链路的隐性问题,导致响应体的Mono.just(new FreshStatus(true))未被正确触发序列化,最终返回空白。
修复代码
@Bean public RouterFunction<ServerResponse> refresh() { return route(GET("/api/refresh"), (request) -> ServerResponse.ok().body( request.principal() .map(it -> new FreshStatus(true)) .defaultIfEmpty(new FreshStatus(false)), FreshStatus.class ) ); } record FreshStatus(boolean isFresh) {}
修复逻辑说明
- 用
map将已认证的Principal直接映射为FreshStatus(true),确保认证场景生成正确响应数据 - 用
defaultIfEmpty(new FreshStatus(false))兜底处理未认证场景,避免返回空Mono - 将整个
Mono<FreshStatus>作为响应体传入ServerResponse.ok().body(),保证无论是否认证,都会生成包含有效内容的200响应
内容的提问来源于stack exchange,提问作者Vinz243
相关产品推荐
相关产品推荐

