Задержка весеннего вызова веб-клиента с помощью ScheduledExecutorService не ожидает ответа

#java #spring-boot

#Ява #пружинный ботинок

Вопрос:

Учитывая простой контроллер REST и метод обслуживания (Spring Boot 2.5.x и Java 8), как я могу добиться следующего?

  1. Клиент отправляет некоторые данные контроллеру REST.
  2. Контроллер вызывает сервисный метод.
  3. Сервисный метод должен вызвать вызов REST для внешнего API с использованием WebClient после фиксированной задержки, например, 10 секунд.

В то время как 1. и 2. являются тривиальными, я борюсь с 3. Моя первая реализация выглядит следующим образом, с использованием ScheduledExecutorService А. Это на самом деле задерживает выполнение sendNotification() , но кажется, что результат этого вызова REST игнорируется. Если внешний API возвращает, например, HTTP 4xx/5xx, я ожидал WebClientResponseException бы, но этого не происходит.

Может быть, это как-то связано с проблемой ScheduledExecutorService и какой-то темой?

Класс контроллера ОТДЫХА

 @RestController @RequiredArgsConstructor public class ServiceController {   private final SampleService sampleService;   @PostMapping(value = "/api")  public String create(@RequestBody SampleRequest sampleRequest) {  return sampleService.create(sampleRequest);  } }  

Класс обслуживания

 @Service @RequiredArgsConstructor public class SampleService {   private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();   public String create(SampleRequest sampleRequest) {  final String result = processSampleRequest(sampleRequest);  executorService.schedule(() -gt; sendNotification(), 10, TimeUnit.SECONDS);  return result;  }   public void sendNotification() {  final WebClient webClient = WebClient.builder()  .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)  .build();  webClient.post()  .uri("http://localhost:5555")  .body(BodyInserters.fromValue("some string"))  .retrieve()  .toBodilessEntity()  .block();   } }  

Комментарии:

1. Вы не обрабатываете исключение в sendNotification, позвольте добавить try/catch … и мне интересно, что вы делаете с этим исключением? Бросить его на службу или что-то в этом роде?

2. Спасибо, что указали мне правильное направление. Вот что, я думаю, происходит: контроллер на самом деле закончил свою работу, пока sendNotification() работает «вне» контекста контроллера. Таким образом, мой RestControllerAdvice не срабатывает.

3. Да, если вы хотите, чтобы RestControllerAdvice перехватил ваше исключение, поэтому вы должны запустить его внутри службы, поэтому служба ExecutorService здесь бессмысленна, потому что вам нужно дождаться результата webclient… чтобы проверить ошибку статуса… что-то совсем запутано в ваших требованиях

4. Что должно произойти на стороне клиента в случае sendNotification сбоя? Имеет ли этот ответ какое-либо значение для клиента? В настоящее время клиент немедленно получит строку результата, и любая ошибка в sendNotification ней останется незамеченной.