Чтение контента из 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);
}