WebClient bodyToMono遇空响应体时的预期行为咨询
回答:bodyToMono处理空响应体的行为是预期的吗?
这确实是bodyToMono的预期行为,下面来拆解背后的原因:
1. bodyToMono的设计逻辑
Reactor Netty的bodyToMono方法在处理HTTP响应时,会区分两种核心场景:
- 当响应体存在但解析失败(比如JSON格式错误、字段类型不匹配):此时会抛出解析异常,进入
doOnError块。 - 当响应体完全为空:框架会直接返回一个
Mono.empty(),而不是抛出错误。这是因为HTTP协议本身允许错误状态码(比如404 Not Found、401 Unauthorized)搭配空响应体,这种场景被视为合法的服务器响应,而非解析错误。
2. 为什么必填字段的对象不会触发错误?
你提到ErrorResponse包含必填字段,但bodyToMono只有在尝试解析内容但不符合对象结构时才会触发校验错误。如果没有响应体,它根本不会执行解析逻辑——也就不会去校验必填字段是否存在,自然不会抛出解析异常。
3. 你的修复方案是合理的
你添加的switchIfEmpty正是解决这个场景的正确方式:
.retrieve() .onStatus(HttpStatus::isError) { response -> response.bodyToMono(ErrorResponse::class.java) .switchIfEmpty { throw RuntimeException("Received Empty Response Body") } .doOnError { throw APIException( code = UNEXPECTED_RESPONSE_CODE, reason = it.message ?: "Could not parse error response from Inventory Availability", httpStatus = response.statusCode() ) } .map { throw APIException( reason = it.errors.reason, code = it.errors.code, httpStatus = response.statusCode() ) } }
这个逻辑会在bodyToMono返回空Mono时,主动抛出异常,确保所有错误状态码的响应都会进入你的自定义错误处理流程,不会出现无错误返回的情况。
如果想更严谨,也可以提前通过response.headers().contentLength()判断是否为空体,但switchIfEmpty已经足够简洁且覆盖场景。
内容的提问来源于stack exchange,提问作者chas spenlau
相关产品推荐
相关产品推荐

