我正在使用Spring 5反应堆中的WebFlux HTTP Client访问外部REST服务。我想根据HTTP状态处理响应:
如果状态为2xx,我想返回带有反序列化响应正文的Mono
。
如果状态为404,我想删除响应正文并立即返回空Mono
。
对于其他任何状态,我想删除响应正文并使用MyBusinessException
返回错误Mono。
我的代码如下:
webClient.get()
.uri("/search")
.syncBody(request)
.exchange()
.flatMap { response ->
when {
response.statusCode().is2xxSuccessful -> response.bodyToMono(MyResponse::class.java)
response.statusCode() == NOT_FOUND -> Mono.empty()
else -> MyBusinessException().toMono<MyResponse>()
}
}
我不想在不需要时浪费时间来接收和处理响应正文。 exchange()
方法状态的JavaDoc
您必须始终使用响应的主体或实体方法之一,以确保释放资源。
如果我要耗尽响应主体并立即返回结果,该怎么做?
答案 0 :(得分:1)
需要耗尽响应,以便可以将连接重用于以后的请求(即http keep-alive /持久连接)。
要返回一个空的Mono
,该文本将在排空正文后完成(忽略错误):
// drain the body
response.body(BodyExtractors.toDataBuffers())
// release DataBuffers
.doOnNext(DataBufferUtils::release)
// ignore errors
.onErrorResume(exception -> Mono.empty())
// return an empty Mono
.then();
要返回立即完成的空Mono
,并在后台异步消耗主体(忽略错误):
Mono.<Void>empty()
.doOnSubscribe(s ->
// drain the body
response.body(BodyExtractors.toDataBuffers())
// release DataBuffers
.doOnNext(DataBufferUtils::release)
// initiate drain on a separate Scheduler
.subscribeOn(Schedulers.parallel())
// subscribe, and ignore errors
.subscribe())
我仍然建议第一种选择,因为它会立即释放资源,并且可能是WebClient
开发人员在编写和记录其用法时所想到的。
我从未在生产系统中使用过第二个选项,因此请进行您自己的测试,以确保http连接池的行为符合预期。如果使用react-netty,则可以在reactor.netty.resources.PooledConnectionProvider
上启用调试日志记录以比较这两种方法。