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
相关产品推荐
相关产品推荐

