В Java этот код выдает исключение, когда результат HTTP составляет диапазон 404:
URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!
В моем случае я знаю, что это 404, но я все равно хотел бы прочитать текст ответа.
(В моем фактическом случае код ответа - 403, но основная часть ответа объясняет причину отказа, и я хотел бы показать это пользователю.)
Как я могу получить доступ к телу ответа?
java
http
httpurlconnection
Дэн Фабулич
источник
источник
Ответы:
Вот отчет об ошибке (закрыть, не исправлю, не ошибка).
Их совет заключается в следующем:
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection; InputStream _is; if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) { _is = httpConn.getInputStream(); } else { /* error from server */ _is = httpConn.getErrorStream(); }
источник
httpConn.getResponseCode() >= 400
(и их обходной путь содержит ошибку, переключая входные потоки для использования)Это та же проблема, что и у меня:
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, которое дает доступ к потоку при исключении. Так что я думаю, это хороший способ для 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(); }
источник
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
Мой рабочий код.
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);
источник
Как прочитать тело ответа 404 в java:
Используйте библиотеку Apache - https://hc.apache.org/httpcomponents-client-4.5.x/httpclient/apidocs/
или Java 11 - https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html
В приведенном ниже фрагменте используется Apache:
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.util.EntityUtils; CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse resp = client.execute(new HttpGet(domainName + "/blablablabla.html")); String response = EntityUtils.toString(resp.getEntity());
источник