Чтение контента из http-ответа клиента Google несколько раз в пакетном запросе

Следуя документации Google Drive REST API, я реализую стратегию экспоненциальной отсрочки для исправляемых ошибок API. Я хотел бы повторить мой запрос, если код ошибки 500 или 403 (и, возможно, 429), но я заметил, что не все ошибки 403 исправимы, поэтому я хотел бы повторить попытку только для тех, у которых есть причина в выбранном списке, Причина ошибки не указана в ответе как отдельная информация, но она содержится во входном потоке контента, который я проанализировал и обработал:

private boolean isRateLimitExceeded(com.google.api.client.http.HttpResponse response) {
    int statusCode = response.getStatusCode();
    if (statusCode == 403) {
        response.getRequest().setParser(Utils.getDefaultJsonFactory().createJsonObjectParser());
        GoogleJsonErrorContainer jsonResponse = response.parseAs(GoogleJsonErrorContainer.class);
        List<ErrorInfo> errors = jsonResponse.getError().getErrors();
        if (errors != null && !errors.isEmpty()) {
            List<String> recoverableErrors = Arrays.asList("limitExceeded", "concurrentLimitExceeded", "rateLimitExceeded", "userRateLimitExceeded", "servingLimitExceeded");
            for (ErrorInfo errorInfo : errors) {
                if (!recoverableErrors.contains(errorInfo.getReason())) {
                    return false;
                }
            }
            return true;
        }
    }
    return false;
}

Это работает нормально, но потребляет контент. Во время выполнения пакетного запроса клиент Google пытается снова прочитать и проанализировать контент, не находит ничего и выдает исключение. Я пытался пометить и сбросить входной поток response.getContent(), но HttpResponse от Google не поддерживает маркировку. Есть ли другой способ сделать контент доступным снова или прочитать его, не потребляя его?

Если это имеет значение, я использую GoogleNetHttpTransport.

1 ответ

Я считаю, что это правильный способ сделать это:

private static final String USER_RATE_LIMIT_EXCEEDED_REASON = "userRateLimitExceeded";
private static final String RATE_LIMIT_EXCEEDED_REASON = "rateLimitExceeded";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

private boolean isRateLimitExceeded(HttpResponse response) {
    return response.getStatusCode() == HttpStatusCodes.STATUS_CODE_FORBIDDEN
            && isRateLimitExceeded(GoogleJsonResponseException.from(JSON_FACTORY, response));
}

private boolean isRateLimitExceeded(GoogleJsonResponseException ex) {
    if (ex.getDetails() == null || CollectionUtils.isEmpty(ex.getDetails().getErrors())) {
        return false;
    }
    String reason = ex.getDetails().getErrors().get(0).getReason();
    return RATE_LIMIT_EXCEEDED_REASON.equals(reason) || USER_RATE_LIMIT_EXCEEDED_REASON.equals(reason);
}

Смотрите также: https://www.programcreek.com/java-api-examples/?code=cchabanois/mesfavoris/mesfavoris-master/bundles/mesfavoris.gdrive/src/mesfavoris/gdrive/connection/GDriveBackOffHttpRequestInitializer.java

Другие вопросы по тегам