Spring WebClient - цепочка асин c звонков - PullRequest
0 голосов
/ 12 апреля 2020

Я создаю простое старое Java настольное приложение с Swing, но мне нужно сделать вызовы Rest для внутреннего интерфейса. Поскольку мы находимся в современном асинхронном мире c и инструменты существуют, я хочу сделать асин c вызовы бэкэнда, отобразить индикатор выполнения и скрыть его после завершения вызовов.

Использование Spring WebClient кажется способом go, и он работает хорошо, пока мне не нужно объединить несколько асин c Rest вызовов. В этом случае второй вызов никогда не отвечает ... Я вижу, что бэкэнд действительно получает 2 вызова, но клиентская сторона никогда не возобновляет.

public void notWorking(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    webClient.post()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(toolDto.getTool().getToolId());
            })
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .subscribe(id -> {
                webClient.get()
                        .uri(uriBuilder -> {
                            return uriBuilder
                                    .path("/tools/{id}")
                                    .build(id);
                        })
                        .retrieve()
                        .bodyToMono(ToolDto.class)
                        .subscribe((response) -> {
                            successCallback.accept(response);
                        });
            });
}

Однако, если я делаю те же вызовы, но в блокировке Кстати, все отлично работает. (За исключением того, что это syn c, поэтому моя панель загрузки не будет работать ...)

public void working(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    Long id = webClient.post()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(toolDto.getTool().getToolId());
            })
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .block();

    webClient.get()
            .uri(uriBuilder -> {
                return uriBuilder
                        .path("/tools/{id}")
                        .build(id);
            })
            .retrieve()
            .bodyToMono(ToolDto.class)
            .subscribe((response) -> {
                successCallback.accept(response);
            });
}

1 Ответ

0 голосов
/ 12 апреля 2020

Вы должны стараться избегать вложенных подписок. Вместо этого вы можете использовать flatmap.

public void shouldBeWorking(CurrentTool toolDto, Consumer<ToolDto> successCallback) {
    webClient.post()
            .uri(uriBuilder -> uriBuilder
                    .path("/tools/{id}")
                    .build(toolDto.getTool().getToolId()))
            .body(BodyInserters.fromObject(toolDto.getTool()))
            .retrieve()
            .bodyToMono(Long.class)
            .flatmap(id -> webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/tools/{id}")
                            .build(id))
                    .retrieve()
                    .bodyToMono(ToolDto.class))
            .subscribe(successCallback::accept);
}
...