Вопрос

В 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 возвращает 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....

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

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

В .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();
}

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

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

InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top