use*_*636 5 java spring reactor spring-webclient
我们使用org.springframework.web.reactive.function.client.WebClientwith
reactor.netty.http.client.HttpClient作为 Spring 5.1.9 的一部分来使用该exchange()方法发出请求。此方法的文档强调了以下几点:
...在使用 exchange() 时,无论场景如何(成功、错误、意外数据等),应用程序都有责任使用任何响应内容。不这样做会导致内存泄漏。
我们对 的使用exchange()相当基本,但我不清楚错误场景的文档,我想确定我们是否正确地为所有结果释放了资源。本质上,我们有一个阻塞实现,它发出请求并返回ResponseEntity无论响应代码如何:
try {
...
ClientResponse resp = client.method(method).uri(uri).syncBody(body).exchange().block();
ResponseEntity<String> entity = resp.toEntity(String.class).block();
return entity;
} catch (Exception e) {
// log error details, return internal server error
}
Run Code Online (Sandbox Code Playgroud)
如果我理解实现,exchange()无论响应代码如何(例如 4xx、5xx),如果请求成功发送,将始终给我们一个响应。在这种情况下,我们只需要调用toEntity()即可使用响应。我担心的是错误情况(例如,无响应、低级连接错误等)。上述异常处理是否会捕获所有其他场景,并且它们中的任何一个都有需要消耗的响应?
注意:ClientResponse.releaseBody()仅在 5.2 中引入
小智 7
在发出请求时必须消耗响应,但是如果您不能执行请求,则可能之前抛出了异常,并且响应不会出现问题。
在文档中说:
注意:通过 WebClient exchange() 方法使用 ClientResponse 时,您必须确保使用以下方法之一消耗或释放主体:
- 身体(身体提取器)
- bodyToMono(Class) 或 bodyToMono(ParameterizedTypeReference)
- bodyToFlux(Class) 或 bodyToFlux(ParameterizedTypeReference)
- toEntity (Class) 或 toEntity(ParameterizedTypeReference)
- toEntityList(Class) 或 toEntityList(ParameterizedTypeReference)
- toBodilessEntity()
- 释放体()
如果不需要响应内容,您也可以使用 bodyToMono(Void.class)。但是请记住,如果任何内容确实到达,连接将被关闭,而不是被放回池中。这与 releaseBody() 形成对比,后者确实消耗整个身体并释放收到的任何内容。
您可以尝试使用 .retrieve() 代替 .exchange() 并根据您的喜好处理错误。
public Mono<String> someMethod() {
return webClient.method(method)
.uri(uri)
.retrieve()
.onStatus(
(HttpStatus::isError), // or the code that you want
(it -> handleError(it.statusCode().getReasonPhrase())) //handling error request
)
.bodyToMono(String.class);
}
private Mono<? extends Throwable> handleError(String message) {
log.error(message);
return Mono.error(Exception::new);
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我使用了 Exception 但你可以创建一些更具体的异常,然后使用一些异常处理程序来返回你想要的 http 状态。 不推荐使用block,更好的方法是向前传递流。
| 归档时间: |
|
| 查看次数: |
4559 次 |
| 最近记录: |