Как увеличить время ожидания класса AsyncRestTemplate? - PullRequest
0 голосов
/ 30 мая 2018

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

Если я пытаюсьвосстановить ответ веб-службы с помощью метода get() в клиенте, и это занимает много времени, я всегда получаю следующее сообщение:

   "timestamp": "2018-05-29T22:42:26.978+0000",
   "status": 500,
   "error": "Internal Server Error",
   "message": "java.util.concurrent.ExecutionException: org.springframework.web.client.HttpServerErrorException: 503 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(100000L);
        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);
        }
    }
}

Я пытался увеличить время ожидания свойства в приложенииФайл .property, но он не работал.

# SPRING MVC (WebMvcProperties)
spring.mvc.async.request-timeout= 500000 # Amount of time before asynchronous request handling times out.

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

1 Ответ

0 голосов
/ 30 января 2019

Для лучшего обслуживания вы можете настроить bean-компонент AsyncRestTemplate:

@Bean
public AsyncRestTemplate asyncRestTemplate() {
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setTaskExecutor(new SimpleAsyncTaskExecutor());
    factory.setConnectTimeout(1000);//milliseconds
    factory.setReadTimeout(2000);//milliseconds
    return new AsyncRestTemplate(factory);
}

И затем автоматически подключить этот bean-компонент:

@Autowired
private AsyncRestTemplate restTemplate;

После этого обновите ваш callService:

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

Вы можете удалить аннотацию @Async, поскольку AsyncRestTemplate является асинхронным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...