Как отловить исключения с помощью класса CompletableFuture в веб-службах REST и Spring? - PullRequest
0 голосов
/ 28 мая 2018

Я разработал несколько асинхронных веб-сервисов с Spring Framework и REST, я использовал его от клиента, созданного с классом Spring AsyncRestTemplate.Класс возвращает объект ListenableFuture<ResponseEntity<T>> (с методом getForEntity), который возвращает значение, возвращаемое веб-службой (с методом .get():<T>).Это работает нормально, однако, когда возникает пользовательское исключение в веб-сервисе REST (которое расширяет класс RuntimeException), клиент не перехватывает его правильно и выдает мне следующее сообщение:

"отметка времени": «2018-05-28T14: 25: 15.393 + 0000», «статус»: 500,
«ошибка»: «Внутренняя ошибка сервера», «сообщение»: «java.util.concurrent.ExecutionException: org.springframework.web.client.HttpServerErrorException: 500 null ",
" path ":" / client / result "

Кто-нибудь знает, как я могу решить проблему ?.Я хочу, чтобы клиент показал мне пользовательское сообщение об исключении.

Коды сервера следующие:

Класс конфигурации:

@Configuration
@EnableAsync
public class ConfigurationClass {
    @Bean
    public Executor threadPoolTaskExecutor() {
        return new ThreadPoolTaskExecutor();
    }
}

Класс контроллера:

@RestController
@RequestMapping("/server")
public class ControllerClass {

    @GetMapping("/start")
    @Async
    public CompletableFuture<String>  callService() throws InterruptedException{
        Thread.sleep(10000L);
        if(true)
            throw new RuntimeException("Custom Error");
        return CompletableFuture.completedFuture("OK");
    }
}

Код клиента (потребитель) следующий:

@RestController
@RequestMapping("/client")
public class ControllerClass {

    private ListenableFuture<ResponseEntity<String>> entity;

    @GetMapping("/start")
    @Async
    public void callService() throws InterruptedException {
        AsyncRestTemplate restTemplate = new AsyncRestTemplate();
        entity = restTemplate.getForEntity("http://localhost:8080/server/start",
                 String.class);
    }

    @GetMapping("/state")
    public boolean getState() {
        try {
            return entity.isDone();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/result")
    public ResponseEntity<String> getResult() {
        try {
            return entity.get();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Спасибо за вашу помощь, С уважением.

Добавлен 19/05/2018 ---------------------------------------

Я близок к решению.В классе управления веб-сервисом я добавил метод, помеченный @ExceptionHandler, как в следующем коде:

@ExceptionHandler(RuntimeException.class)
    void handleIllegalArgumentException(HttpServletResponse response) throws IOException {
        response.sendError(200, "custom Error");
    }

Он работает нормально, клиент уже правильно распознал исключение, однако, если я изменяюстатус другим в веб-сервисе (например, 201, 400, 401, которые HTTP действительный статус ), я возвращаюсь, чтобы получить сообщение "java.util.concurrent.ExecutionException: org.springframework.web.client.HttpServerErrorException: 500 null" в клиенте.

Кто-то знает причину?

1 Ответ

0 голосов
/ 29 мая 2018

Когда RestTemplate получает код ответа 4xx или 5xx, он считает его ошибкой и выдает HttpClientErrorException / HttpServerErrorException вместо возврата ResponseEntity.

Для вашего варианта использованияВы можете установить обработчик ошибок (начиная с DefaultResponseErrorHandler), который не считает ответы 4xx и 5xx ошибками.

Вместо

AsyncRestTemplate restTemplate = new AsyncRestTemplate();

используйте следующий код

    AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
    asyncRestTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
        @Override
        protected boolean hasError(HttpStatus statusCode) {
            return false;
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...