首页 > 解决方案 > Spring Boot 异步休息调用

问题描述

我正在尝试创建一个调度程序,它将获取请求发送到 Web 服务并获取我们需要的项目的数量。然后将 Total 除以 per_page 然后发送所需的任意数量的请求,但请求是异步的。

我的代码在我的测试类中运行良好,但在主应用程序中我收到两个基于 JDK 版本的错误

这是我的 API 服务:

    public interface RestService {

    @Async
    CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token);

    UpcomingEventsResponse getUpcomingEvents(String day,String token);
}

我的 RestService 实现:

@Service
@RequiredArgsConstructor
@Slf4j
public class RestServiceImpl implements RestService {

    public static final String UPCOMING_EVENTS_URL = "HTTP://localhost/test";
    private final RestTemplate restTemplate;

    @Override
    public CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token) {
        String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day),createQuery("page", page), createQuery("token", token));

        return makeCallAsync(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
    }

    @Override
    public UpcomingEventsResponse getUpcomingEvents(String day,String token) {
        String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day), createQuery("page", 1), createQuery("token", token));

        return makeCall(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
    }

    private <T> T makeCall(String url,
                           HttpMethod method,
                           HttpEntity<Object> httpEntity,
                           Class<T> outClass) {

        return restTemplate.exchange(url, method, httpEntity, outClass).getBody();
    }

    private <T> CompletableFuture<T> makeCallAsync(String url,
                                                   HttpMethod method,
                                                   HttpEntity<Object> httpEntity,
                                                   Class<T> outClass) {

        return CompletableFuture.completedFuture(restTemplate.exchange(url, method, httpEntity, outClass).getBody());
    }
}

这是我的调度程序类:

@Component
@RequiredArgsConstructor
@Slf4j
public class EventScheduler {

    private final RestService restService;

    //TODO change time
    @Scheduled(cron = "0 */2 * * * *")
    public void getAllEvents(){
        long start = System.currentTimeMillis();

        //TODO add token from database or env

        UpcomingEventsResponse upcomingEvents = restService.getUpcomingEvents(null, "token");

        List<ResultsItem> resultsItems = new ArrayList<>(upcomingEvents.getResults());
        List<CompletableFuture<UpcomingEventsResponse>> completableFutures = new ArrayList<>();

        int repeatTimes = upcomingEvents.getPager().getTotal() / upcomingEvents.getPager().getPerPage();

        for (int i = 0; i < repeatTimes; i++) {

            int page = i + 2;

            CompletableFuture<UpcomingEventsResponse> events = restService.getUpcomingEvents(page, null, "token");
            completableFutures.add(events);
        }

        CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join();

        log.info("Elapsed time: " + (System.currentTimeMillis() - start));

        completableFutures.forEach(completableFuture -> {
            try {
                resultsItems.addAll(completableFuture.get().getResults());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        });
        log.info("Size " + resultsItems.size());
        log.info("Total " + upcomingEvents.getPager().getTotal());
    }

}

这是我在 JDK 8 中遇到的错误:

peer not authenticated; nested exception is javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

这是 JDK 10 或 11 上的错误:

javax.net.ssl.SSLException: No PSK available. Unable to resume

有一个更好的方法吗?问题是什么?这是一个错误吗?

标签: javaspringspring-bootasynchronousresttemplate

解决方案


问题出在Web服务中,虽然我真的无法理解不同JDK中错误的原因。据我所知,这是一个已知的错误,您可以在此处阅读更多信息

这个实现工作得很好,您可以将Apache HTTP Client与 resttemplate 一起使用,但您不能将OkHttpApache HttpClientSpring webflux WebService一起使用


推荐阅读