在 Java 中读取错误响应正文
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/613307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read error response body in Java
提问by Dan Fabulich
In Java, this code throws an exception when the HTTP result is 404 range:
在 Java 中,当 HTTP 结果为 404 范围时,此代码会引发异常:
URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!
In my case, I happen to know that the content is 404, but I'd still like to read the body of the response anyway.
就我而言,我碰巧知道内容是 404,但我仍然想阅读响应的正文。
(In my actual case the response code is 403, but the body of the response explains the reason for rejection, and I'd like to display that to the user.)
(在我的实际情况下,响应代码是 403,但响应的正文解释了拒绝的原因,我想将其显示给用户。)
How can I access the response body?
如何访问响应正文?
采纳答案by TofuBeer
Here is the bug report(close, will not fix, not a bug).
这是错误报告(关闭,不会修复,不是错误)。
Their advice there is to code like this:
他们的建议是这样编码:
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
_is = httpConn.getInputStream();
} else {
/* error from server */
_is = httpConn.getErrorStream();
}
回答by matt b
I know that this doesn't answer the question directly, but instead of using the HTTP connection library provided by Sun, you might want to take a look at Commons HttpClient, which (in my opinion) has a far easier API to work with.
我知道这并不能直接回答问题,但您可能想看看Commons HttpClient,而不是使用 Sun 提供的 HTTP 连接库,它(在我看来)有一个更容易使用的 API。
回答by Chris Dolan
First check the response code and then use HttpURLConnection.getErrorStream()
首先检查响应代码,然后使用 HttpURLConnection.getErrorStream()
回答by TofuBeer
InputStream is = null;
if (httpConn.getResponseCode() !=200) {
is = httpConn.getErrorStream();
} else {
/* error from server */
is = httpConn.getInputStream();
}
回答by gpiazzese
It's the same problem I was having:
HttpUrlConnection
returns FileNotFoundException
if you try to read the getInputStream()
from the connection.
You should instead use getErrorStream()
when the status code is higher than 400.
这与我遇到的问题相同:
如果您尝试从连接中读取,则HttpUrlConnection
返回。当状态代码高于 400 时,
您应该改为使用。FileNotFoundException
getInputStream()
getErrorStream()
More than this, please be careful since it's not only 200 to be the success status code, even 201, 204, etc. are often used as success statuses.
除此之外,请注意,因为成功状态码不仅是200,甚至201、204等也经常被用作成功状态。
Here is an example of how I went to manage it
这是我如何管理它的示例
... 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....
In this way, you'll be able to get the needed response in both success and error cases.
Hope this helps!
通过这种方式,您将能够在成功和错误情况下获得所需的响应。
希望这可以帮助!
回答by Vozzie
In .Net you have the Response property of the WebException that gives access to the stream ON an exception. So i guess this is a good way for Java,...
在 .Net 中,您具有 WebException 的 Response 属性,该属性允许对流进行异常访问。所以我想这是 Java 的好方法,...
private InputStream dispatch(HttpURLConnection http) throws Exception {
try {
return http.getInputStream();
} catch(Exception ex) {
return http.getErrorStream();
}
}
Or an implementation i used. (Might need changes for encoding or other things. Works in current environment.)
或者我使用的一个实现。(可能需要更改编码或其他内容。在当前环境中工作。)
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();
}
回答by Durgesh Kumar
My running code.
我的运行代码。
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);
回答by Esakkiappan .E
How to read 404 response body in java:
如何在java中读取404响应体:
Use Apache library - https://hc.apache.org/httpcomponents-client-4.5.x/httpclient/apidocs/
使用 Apache 库 - https://hc.apache.org/httpcomponents-client-4.5.x/httpclient/apidocs/
or Java 11 - https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html
或 Java 11 - https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html
Snippet given below uses Apache:
下面给出的代码段使用 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());