Чтение сообщения об ошибке в Java - PullRequest
80 голосов
/ 05 марта 2009

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

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

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

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

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

Ответы [ 6 ]

152 голосов
/ 05 марта 2009

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

Их совет: кодировать так:

HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
    _is = httpConn.getInputStream();
} else {
     /* error from server */
    _is = httpConn.getErrorStream();
}
13 голосов
/ 29 июня 2015

Это та же проблема, что и у меня: HttpUrlConnection возвращает FileNotFoundException, если вы пытаетесь прочитать 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....

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

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

10 голосов
/ 17 мая 2016

В .Net у вас есть свойство Response WebException, которое дает доступ к потоку ON, исключение. Так что я думаю, что это хороший способ для 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();
}
2 голосов
/ 05 марта 2009

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

2 голосов
/ 05 марта 2009

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

0 голосов
/ 19 января 2010
InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
...