You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux下ServerResponse提前返回、校验失败分支Mono不执行问题

问题原因

1. 核心通用问题

WebFlux 中 ServerRequest 的请求体是仅支持单次消费的数据流,你在两个方案中都多次调用了 request.bodyToMono(OrderDto.class) 读取请求体:第一次读取做校验时已经把数据流消费完,第二次调用读取会直接拿到空的Mono,导致逻辑中断无响应。

2. 方案1专属问题

校验失败分支中引用了未定义的变量 list,实际应该使用当前作用域内的校验结果变量 listErrors,存在语法错误,分支逻辑无法正常执行。

3. 方案2专属问题

逻辑末尾统一调用 ServerResponse.badRequest() 构建响应,就算校验通过执行业务逻辑,返回结果也会被强制包装为400状态码;同时同样存在重复读取请求体的问题,校验通过分支执行时读取不到请求体导致无响应。

4. 额外潜在问题

你的校验方法中存在语法笔误:request.getId == null 缺少方法调用括号,正确写法应为 request.getId() == null,该问题也会导致校验逻辑无法正常执行。

修复方案

只读取一次请求体,缓存后复用即可:

public Mono<ServerResponse> startOrder(ServerRequest request) {
    // 仅消费一次请求体,后续逻辑复用该实例
    return request.bodyToMono(OrderDto.class)
            .flatMap(orderDto -> {
                List<String> listErrors = Utils.validate(orderDto);
                if (listErrors.isEmpty()) {
                    // 直接传入缓存的orderDto,无需再次读取request
                    return this.service.startOrder(Mono.just(orderDto))
                            .flatMap(orderResponse -> ServerResponse.ok().bodyValue(orderResponse));
                }
                // 校验失败直接返回400
                OrderResponse errorRes = new OrderResponse(HttpStatus.BAD_REQUEST.value(), new ApiError(listErrors.toString()));
                return ServerResponse.badRequest().bodyValue(errorRes);
            });
}

内容的提问来源于stack exchange,提问作者tnaluat tnaluat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:18:01