Чтение тела ответа на ошибку в Java
В Java этот код генерирует исключение, когда результат HTTP равен 404:
URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!
В моем случае, я знаю, что содержание 404, но я все равно хотел бы прочитать тело ответа в любом случае.
(В моем фактическом случае код ответа равен 403, но тело ответа объясняет причину отклонения, и я хотел бы отобразить это для пользователя.)
Как я могу получить доступ к телу ответа?
Ответы
Ответ 1
Вот отчет об ошибке (закрыть, не исправить, а не ошибка).
Их советы заключаются в следующем:
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
_is = httpConn.getInputStream();
} else {
/* error from server */
_is = httpConn.getErrorStream();
}
Ответ 2
Это та же проблема, что и у меня:
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....
Таким образом, вы сможете получить необходимый ответ как в случае успеха, так и в случае ошибок.
Надеюсь, это поможет!
Ответ 3
В .Net у вас есть свойство Response для WebException, которое дает доступ к потоку в качестве исключения. Поэтому я думаю, что это хороший способ для 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();
}
Ответ 4
Я знаю, что это не отвечает на вопрос напрямую, но вместо использования библиотеки HTTP-соединений, предоставляемой Sun, вы можете взглянуть на Commons HttpClient, который (на мой взгляд) имеет гораздо более простой API для работы.
Ответ 5
Сначала проверьте код ответа, а затем используйте HttpURLConnection.getErrorStream()
Ответ 6
InputStream is = null;
if (httpConn.getResponseCode() !=200) {
is = httpConn.getErrorStream();
} else {
/* error from server */
is = httpConn.getInputStream();
}
Ответ 7
Мой бегущий код.
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
in = new InputStreamReader(urlConn.getInputStream());
BufferedReader bufferedReader = new BufferedReader(in);
if (bufferedReader != null) {
int cp;
while ((cp = bufferedReader.read()) != -1) {
sb.append((char) cp);
}
bufferedReader.close();
}
in.close();
} else {
/* error from server */
in = new InputStreamReader(httpConn.getErrorStream());
BufferedReader bufferedReader = new BufferedReader(in);
if (bufferedReader != null) {
int cp;
while ((cp = bufferedReader.read()) != -1) {
sb.append((char) cp);
}
bufferedReader.close();
}
in.close();
}
System.out.println("sb="+sb);