У нас есть две части в нашем приложении:
Сервер - предоставлять услуги REST
Клиент - потреблять их через Spring restTemplate
В дополнение к статусу HTTP наш сервер возвращает тело HTTP с JSON, которое подробно описывает ошибку. Итак, я добавил собственный обработчик ошибок в restTemplate для обработки некоторых закодированных ошибок как ошибок - это помогает очень хорошо анализировать тело HTTP.
Но я получаю исключение путем анализа тела HTTP в случае HTTP/1.1 401 Unauthorized. Все остальные коды ошибок обрабатываются нормально (400, 402 и т.д.) Мы используем простую серверную логику, которая отправляет HTTP-ответ в случае ошибки, никаких специальных правил для различных типов ошибок:
writeErrorToResponse(int status, String errMsg, HttpServletResponse resp) throws IOException {
response.setStatus(status);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
String message = String.format("{\"error\":\"%s\"}", StringUtils.escapeJson(errMsg));
resp.getWriter().println(message);
}
Но на клиенте только HTTP/1.1 401 выдает исключение - "java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode"
Я сделал некоторые отладки и вижу, что причиной проблемы является код в SimpleClientHttpResponse:
HttpURLConnection.getInputStream()
Трассировка с Fiddler имеет следующие ответы: Сообщение правильно проанализировано на клиенте:
HTTP/1.1 402 Payment Required
X-Powered-By: Servlet/3.0
Content-Type: application/json
Content-Language: en-GB
Content-Length: 55
Connection: Close
Date: Sat, 25 May 2013 10:10:44 GMT
Server: WebSphere Application Server/8.0
{"error":"I cant find that user. Please try again."}
И сообщение, которое является причиной исключения:
HTTP/1.1 401 Unauthorized
X-Powered-By: Servlet/3.0
Content-Type: application/json
Content-Language: en-GB
Content-Length: 55
Date: Sat, 25 May 2013 11:00:21 GMT
Server: WebSphere Application Server/8.0
{"error":"I cant find that user. Please try again."}
Что может быть причиной java.net.HttpRetryException в этой ситуации?
Кроме того: несколько раз назад этот механизм работал нормально. Но так как мы изменили много кода в приложении.