在Java中读取错误响应主体

在Java中,当HTTP结果为404范围时,此代码将引发exception:

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

就我而言,我碰巧知道内容是404,但是我仍然喜欢读取响应的主体。

(在我的实际情况下,响应代码是403,但是响应的主体解释了拒绝的原因,我想将其显示给用户。)

我如何访问响应主体?

这里是错误报告 (closures,不会修复,不是一个错误)。

他们的build议是这样的代码:

 HttpURLConnection httpConn = (HttpURLConnection)_urlConnection; InputStream _is; if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) { _is = httpConn.getInputStream(); } else { /* error from server */ _is = httpConn.getErrorStream(); } 

这是我遇到的同样的问题:如果您尝试从连接读取getInputStream()HttpUrlConnection返回FileNotFoundException
当状态码高于400时,应该使用getErrorStream()

除此之外,请注意,成功状态代码不仅有200个,即使是201,204等也经常用作成功状态。

这是我如何去pipe理它的一个例子

 ... 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中,您有WebException的Response属性,可以访问stream上的exception。 所以我想这是一个很好的方法为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(); } 

我知道这不是直接回答这个问题,而是使用Sun提供的HTTP连接库,而不是使用Commons HttpClient ,在我看来,它有一个更简单的API来处理。

首先检查响应代码,然后使用HttpURLConnection.getErrorStream()

 InputStream is = null; if (httpConn.getResponseCode() !=200) { is = httpConn.getErrorStream(); } else { /* error from server */ is = httpConn.getInputStream(); }