Читать тело сообщения об ошибке в Java
в Java этот код создает исключение, когда результатом HTTP является диапазон 404:
URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!
в моем случае, я случайно знаю, что содержание 404, но я все равно хотел бы прочитать тело ответа в любом случае.
(в моем фактическом случае код ответа 403, но тело ответа объясняет причину отказа, и я хотел бы показать это пользователю.)
Как я могу получить доступ к телу ответа?
6 ответов:
вот сообщение об ошибке (закрыть, не исправит, не ошибка).
их совет там кодировать так:
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, которое дает доступ к потоку в исключении. Поэтому я думаю, что это хороший способ для 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 для работы.
InputStream is = null; if (httpConn.getResponseCode() !=200) { is = httpConn.getErrorStream(); } else { /* error from server */ is = httpConn.getInputStream(); }
Comments