spring-boot - WebClient 的 bodyToMono 关于空体预期行为

标签 spring-boot kotlin error-handling spring-webflux spring-webclient

当 WebClient bodyToMono 遇到空主体时,预期的行为是什么?在我的具体示例中,我们正在检查从 post 调用返回的状态,如果将其转换为我们的自定义错误格式是错误的。如果转换为自定义错误格式失败,我们会在自定义格式中创建一个新错误,说明这一点。但是,当响应是一个空主体的错误时,它根本没有发回任何错误,因为 bodyToMono 没有像我预期的那样失败。请参见下面的代码块:

.retrieve()
.onStatus(HttpStatus::isError) { response ->
    response.bodyToMono(ErrorResponse::class.java)
        .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()
            )
        }
}

为了解决这个问题,我们添加了 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 的预期行为吗?由于我明确要求将响应主体映射到我的 ErrorResponse 对象,我希望一个空主体出错,然后点击 doOnError block ,但它只是“成功”/返回一个空单声道......因此我们添加switchIfEmpty block 。如果我们映射到的对象具有可为空的字段,我可以看到它没有错误,但是由于所有字段都是必需的,为什么 bodyToMono 在尝试将“无”映射到我的对象时不会抛出错误?

最佳答案

这是对的。一个 Mono 可以产生 0..1 个元素,而一个空主体只产生一个完成而不发出值的单声道,就像 Mono.empty()。

如果您的用例中没有正文错误,您可以在单声道上调用 .single() 。

关于spring-boot - WebClient 的 bodyToMono 关于空体预期行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56060137/

相关文章:

spring-boot - 当我在响应正文中返回值时,Spring WebFlux 抛出 'producer' 类型未知

Android - 如何打开免提电话和最大通话音量

spring-boot - @Column (Cassandra) 注释被 Spring Boot 2.5.0 忽略(适用于 2.4.6)

python - 当 URL 错误时 PhantomJS 不返回错误(python)

java - 从 .jar 手动启动 Spring Boot 应用程序无法正常工作

mysql - 无法从类型 [java.lang.Object[]] 转换为类型 [@org.springframework.data.jpa.repository.Query

android - 如何在 onResponse 中添加可组合文本? Jetapck Compose

VB6 - 如何在运行时捕获异常或错误

python - 在 Django 错误邮件中包含局部变量

json - <不可读> 对于 100000 字节或以上的 POST 正文长度,也适用于 blob/FormData