Чтение тела ответа на ошибку в Java

В Java этот код генерирует исключение, когда результат HTTP равен 404:

URL url = new URL("http://stackoverflow.com/asdf404notfound"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.getInputStream(); // throws! 

В моем случае, я знаю, что содержание 404, но я все равно хотел бы прочитать тело ответа в любом случае.

(В моем случае код ответа равен 403, но тело ответа объясняет причину отклонения, и я хотел бы отобразить это для пользователя.)

Как я могу получить доступ к органу реагирования?

Вот отчет об ошибке (закрыть, не исправить, а не ошибка).

Их совет заключается в следующем:

 HttpURLConnection httpConn = (HttpURLConnection)_urlConnection; InputStream _is; if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) { _is = httpConn.getInputStream(); } else { /* error from server */ _is = httpConn.getErrorStream(); } 

Это та же проблема, с которой я HttpUrlConnection : HttpUrlConnection возвращает HttpUrlConnection если вы попытаетесь прочитать getInputStream() из соединения.
Вместо этого вы должны использовать getErrorStream() когда код состояния превышает 400.

Более того, будьте осторожны, потому что не только 200 – код статуса успеха, даже 201, 204 и т. Д. Часто используются как статусы успеха.

Вот пример того, как я пошел, чтобы справиться с этим

 ... connection code code code ... // Get the response code int statusCode = connection.getResponseCode(); InputStream is = null; if (statusCode >= 200 && statusCode < 400) { // Create an InputStream in order to extract the response object is = connection.getInputStream(); } else { is = connection.getErrorStream(); } ... callback/response to your handler.... 

Таким образом, вы сможете получить необходимый ответ как в случае успеха, так и в случае ошибок.

Надеюсь это поможет!

В .Net у вас есть свойство Response для WebException, которое дает доступ к streamу в качестве исключения. Поэтому я думаю, что это хороший способ для Java, …

 private InputStream dispatch(HttpURLConnection http) throws Exception { try { return http.getInputStream(); } catch(Exception ex) { return http.getErrorStream(); } } 

Или реализация, которую я использовал. (Могут потребоваться изменения для кодирования или другие вещи. Работает в текущей среде.)

 private String dispatch(HttpURLConnection http) throws Exception { try { return readStream(http.getInputStream()); } catch(Exception ex) { readAndThrowError(http); return null; // <- never gets here, previous statement throws an error } } private void readAndThrowError(HttpURLConnection http) throws Exception { if (http.getContentLengthLong() > 0 && http.getContentType().contains("application/json")) { String json = this.readStream(http.getErrorStream()); Object oson = this.mapper.readValue(json, Object.class); json = this.mapper.writer().withDefaultPrettyPrinter().writeValueAsString(oson); throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage() + "\n" + json); } else { throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage()); } } private String readStream(InputStream stream) throws Exception { StringBuilder builder = new StringBuilder(); try (BufferedReader in = new BufferedReader(new InputStreamReader(stream))) { String line; while ((line = in.readLine()) != null) { builder.append(line); // + "\r\n"(no need, json has no line breaks!) } in.close(); } System.out.println("JSON: " + builder.toString()); return builder.toString(); } 

Я знаю, что это напрямую не отвечает на вопрос, но вместо использования библиотеки HTTP-соединений, предоставляемой Sun, вы можете взглянуть на Commons HttpClient , который (на мой взгляд) имеет гораздо более простой API для работы.

Сначала проверьте код ответа, а затем используйте HttpURLConnection.getErrorStream()

 InputStream is = null; if (httpConn.getResponseCode() !=200) { is = httpConn.getErrorStream(); } else { /* error from server */ is = httpConn.getInputStream(); } 
  • Как избежать Java-кода в JSP-файлах?
  • Создание случайного числа между 1 и 10 Java
  • Динамический типичный ввод в Java
  • Производительность математических математических библиотек Java?
  • Как установить цвет для определенной строки, если определенные условия выполняются с помощью java?
  • Изменение формата даты строки
  • Null check chain vs catching NullPointerException
  • Как запретить Gson преобразовывать длинное число (строка json) в формат научной нотации?
  • Странное поведение со сканером # nextFloat
  • Как проверить, существует ли URL-адрес или возвращает 404 с Java?
  • Что-то кажется неправильным в макете, JButton показывает неожиданное поведение при изменении размера windows
  • Interesting Posts

    Как скрыть окно cmd во время запуска пакетного файла?

    Ограничение доступа для детей и полей с помощью правил безопасности

    Зачем использовать простые свойства вместо полей в C #?

    Преобразуйте double в BigDecimal и установите BigDecimal Precision

    Как закрыть приложение OS X из командной строки с помощью псевдонима, определенного в моем .bash_profile?

    Как сборщик мусора Java обрабатывает саморекламу?

    Повторное использование ячейки TableView и нежелательные галочки – это убивает меня

    Расширение массива в TypeScript

    Как я могу принудительно выполнить полную обратную связь с помощью кнопки в UpdatePanel?

    Почему приложения для ОС Windows 10 загадочно запускаются в качестве фоновых процессов?

    jQuery autocomplete tagging plug-in, как tags ввода StackOverflow?

    Должен ли я использовать одиночные двоеточия (:) или двойные двоеточия (: :) для псевдо-элементов до, после, первой буквы и первой строки?

    Где iPhone Simulator хранит свои данные?

    Безопасное удаление файлов на SSD

    Отправка изображений с помощью Http Post

    Давайте будем гением компьютера.