如何获取HttpClient返回的状态码和响应体?

63

我正在尝试使用Apache HttpClient发出HTTP请求,然后显示HTTP响应代码(200、404、500等)以及HTTP响应正文(文本字符串)。需要注意的是,我正在使用v4.2.2,因为大多数HttpClient示例都来自v.3.x.x,而从版本3到版本4的API发生了很大的变化。

不幸的是,我只能让HttpClient返回状态码响应正文(但不能同时返回两者)。

这是我的代码:

// Getting the status code.
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://whatever.blah.com");
HttpResponse resp = client.execute(httpGet);

int statusCode = resp.getStatusLine().getStatusCode();


// Getting the response body.
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://whatever.blah.com");
ResponseHandler<String> handler = new BasicResponseHandler();

String body = client.execute(httpGet, handler);

所以我问:使用v4.2.2库,如何从同一client.execute(...)调用中获取状态码和响应体?


1
当您尝试从同一个调用中读取两个值时会发生什么?据我所知,这应该没有问题。另外,请记住,对于错误代码,服务器可能根本不发送任何内容(例如,如果不存在whatever.blah.com服务器)。 - SJuan76
请参见https://dev59.com/Wm025IYBdhLWcg3w1ZkL。 - Vadzim
我已将此添加到项目的Jira板 https://issues.apache.org/jira/browse/HTTPCLIENT-1581 - javamonkey79
5个回答

76
不要将处理程序提供给execute。获取HttpResponse对象,使用处理程序获取正文,并直接从中获取状态代码。
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
    final HttpGet httpGet = new HttpGet(GET_URL);

    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        StatusLine statusLine = response.getStatusLine();
        System.out.println(statusLine.getStatusCode() + " " + statusLine.getReasonPhrase());
        String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        System.out.println("Response body: " + responseBody);
    }
}

对于快速单个调用,流畅的 API 非常有用:

Response response = Request.Get(uri)
        .connectTimeout(MILLIS_ONE_SECOND)
        .socketTimeout(MILLIS_ONE_SECOND)
        .execute();
HttpResponse httpResponse = response.returnResponse();
StatusLine statusLine = httpResponse.getStatusLine();

对于较旧版本的Java或HttpComponents,代码可能会有所不同。


3
这仅适用于2xx状态,如果使用BasicResponseHandler处理其他状态将会抛出异常,可以参考我的答案 - eskatos
你救了我的一天,伙计。想知道如果没有 Stack Overflow,开发世界会是什么样子。:-) - Ajay Kumar

37
您可以避免使用BasicResponseHandler,而是直接使用HttpResponse本身获取状态和响应(以字符串形式)。
HttpResponse response = httpClient.execute(get);

// Getting the status code.
int statusCode = response.getStatusLine().getStatusCode();

// Getting the response body.
String responseBody = EntityUtils.toString(response.getEntity());

15

BasicResponseHandler会在状态码不是2xx时抛出异常。请查看其javadoc

以下是我的方法:

HttpResponse response = client.execute( get );
int code = response.getStatusLine().getStatusCode();
InputStream body = response.getEntity().getContent();
// Read the body stream

或者,您还可以从BasicResponseHandler源代码开始编写一个ResponseHandler,当状态不是2xx时不会抛出异常。


6

流畅的外观API:

Response response = Request.Get(uri)
        .connectTimeout(MILLIS_ONE_SECOND)
        .socketTimeout(MILLIS_ONE_SECOND)
        .execute();
HttpResponse httpResponse = response.returnResponse();
StatusLine statusLine = httpResponse.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
    // 响应内容编码自适应?(好像没那么智能)
    String responseContent = EntityUtils.toString(
            httpResponse.getEntity(), StandardCharsets.UTF_8.name());
}

1
如果您正在使用Spring

return new ResponseEntity<String>("your response", HttpStatus.ACCEPTED);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接