我正面临与WebClient和的问题reactor-extra。确实,我有以下方法:
public Employee getEmployee(String employeeId) {
return webClient.get()
.uri(FIND_EMPLOYEE_BY_ID_URL, employeeId)
.retrieve()
.onStatus(HttpStatus.NOT_FOUND::equals, clientResponse -> Mono.empty())
.onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new MyCustomException("Something went wrong calling getEmployeeById")))
.bodyToMono(Employee.class)
.retryWhen(Retry.onlyIf(ConnectTimeoutException.class)
.fixedBackoff(Duration.ofSeconds(10))
.retryMax(3))
.block();
}
Run Code Online (Sandbox Code Playgroud)
我发现我可以使用,retryWhen(Retry.onlyIf(...))因为我只想在ConnectTimeoutException抛出a 时重试。我从这篇文章中找到了这个解决方案:spring webclient: retry with backoff on specific error
但是,在reactor以下方法的最新版本中已弃用:
public final Mono<T> retryWhen(Function<Flux<Throwable>, ? extends Publisher<?>> whenFactory)
谷歌搜索后,我还没有发现任何解决这个问题的时间:是否有任何替代retryWhen和Retry.onlyIf使用的最新版本reactor
谢谢你的帮助 !
reactive-programming spring-boot project-reactor reactor-netty spring-webclient
有没有办法使用默认的 Reactor NettyRequestBody在@ExceptionHandler使用 Spring WebFlux的方法中访问(最好以它的映射形式)?
考虑以下示例:
@RestController
class TestRestController {
@PostMapping("/test")
Mono<TestBody> testPost(@RequestBody TestBody testBody) {
return Mono.error(new NullPointerException());
}
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
Mono<Void> handleNullPointerException(ServerWebExchange serverWebExchange) {
return Mono.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
在运行时,可以将某些类型的其他实例注入到@ExceptionHandler的方法签名中,如上面带有ServerWebExchange. 但是文档明确指出它不支持请求正文参数(请参阅本节中的注释)。
使用 Servlet 堆栈,您可以RequestContext按此处所示注入。WebFlux 堆栈是否有等效或类似的方法?
如何访问 Spring WebFlux 中的请求正文Webfilter?
假设您想要构建一个过滤器来记录请求详细信息,包括所有错误的完整请求正文。
该WebFilter::filter方法提供了ServerWebExchange,可用于检索ServerHttpRequest具有getBody返回 的方法的Flux<DataBuffer>。考虑这个不起作用的例子:
@Component
@Slf4j
public class ErrorWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return
chain.filter(exchange)
.thenReturn(exchange.getResponse())
.map(ServerHttpResponse::getStatusCode)
.filter(HttpStatus::isError)
.then(
exchange.getRequest().getBody()
.map(dataBuffer -> dataBuffer.toString(StandardCharsets.UTF_8))
.collect(Collectors.joining())
.map(Optional::of)
.defaultIfEmpty(Optional.empty())
)
.doOnNext(requestBody -> {
log.info("Error response with statusCode='{}' returned for request: {} {} with query params='{}' with body='{}'.",
exchange.getResponse().getRawStatusCode(),
exchange.getRequest().getMethod(),
exchange.getRequest().getPath(),
exchange.getRequest().getQueryParams(),
requestBody.orElse("")
);
})
.then();
}
}
Run Code Online (Sandbox Code Playgroud)
在我们所有的测试中,上述方法不起作用,因为ServerHttpRequest::getBody返回一个 …
我注意到它Schedulers.enableMetrics()已被弃用,但我不知道应该做什么才能在典型用例(使用 Spring Boot 应用程序)中计量所有调度程序。
Javadoc 建议使用 timedScheduler 但 Spring Boot 应该如何实现呢?