使用 Apatch HttpRequest 的情况下,使用 HttpRequest.execute 方法, 假如该方法抛出了异常,应该从哪个异常中获取到responseEntity String ?我想一定有异常包装了 responseEnity
在使用 Apache HttpClient 时,如果调用 HttpRequest.execute() 抛出了异常,通常情况下,异常不会直接包含完整的 response entity。特别是当服务器返回错误响应(如 4xx 或 5xx 状态码)时,execute() 方法可能抛出各种类型的 IOException 或 HttpResponseException,但这些异常并不一定会携带完整的 response body。
Apache HttpClient 在抛出异常时,通常只会传递有关错误状态的信息(如 HTTP 状态码),而不会包装 response entity。为了从错误响应中提取 response body,你需要手动处理响应,即使发生了异常。
1. 捕获 HttpResponseException
HttpResponseException 是 Apache HttpClient 抛出的常见异常之一,它可以提供 HTTP 状态码,但默认情况下,它不会包含 response entity。你可以通过捕获 HttpResponseException 来处理状态码相关的错误。
try {
CloseableHttpResponse response = httpClient.execute(request);
// 正常处理
} catch (HttpResponseException e) {
// 捕获状态码错误
System.out.println("HTTP Status Code: " + e.getStatusCode());
} catch (IOException e) {
// 其他IO异常处理
e.printStackTrace();
}
然而,HttpResponseException 并不会自动将 response entity 包装在异常中。因此,我们需要另一种方式来在抛出异常时访问 response entity。
2. 如何获取异常中的 response entity
要捕获并读取异常中的 response entity,你可以直接处理响应对象,即使请求导致了异常(如 4xx 或 5xx 错误),并在捕获异常之前手动检查 response 是否有内容可供读取。可以使用 HttpClient 的低级 API 来在异常发生时处理响应体。
3. 使用 responseHandler 捕获 response entity
Apache HttpClient 提供了一种机制——通过 ResponseHandler 可以捕获响应体,即使响应是错误的。通过使用 ResponseHandler,你可以自己定义如何处理成功的响应和错误的响应,并在错误的情况下获取 response entity。
示例代码:使用 ResponseHandler 获取错误响应体
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpClientExample {
public static void main(String[] args) {
String url = "https://example.com/api";
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet request = new HttpGet(url);
// 使用 ResponseHandler 来处理响应
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
@Override
public String handleResponse(final HttpResponse response) throws IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
// 错误情况下捕获response body
HttpEntity entity = response.getEntity();
String errorResponse = entity != null ? EntityUtils.toString(entity) : null;
throw new ClientProtocolException("Unexpected response status: " + status +
", response body: " + errorResponse);
}
}
};
// 这里使用自定义的 ResponseHandler 来执行请求并处理响应
String responseBody = httpClient.execute(request, responseHandler);
System.out.println(responseBody);
} catch (ClientProtocolException e) {
// 捕获并打印异常中的 response body
System.out.println("Exception caught: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
关键点说明:
ResponseHandler:通过自定义的ResponseHandler,你可以在错误响应(如 4xx 或 5xx)时,捕获并读取response entity,而不是让execute()方法直接抛出异常。- 错误处理:在
ResponseHandler中处理状态码大于等于 400 的响应,并将response entity转换为String,即使抛出异常,也可以从异常中获取到响应体。 ClientProtocolException:在异常中,你可以访问状态码以及响应体。
4. 捕获 HttpEntity 并处理异常响应
如果不想使用 ResponseHandler,你可以在捕获异常之前直接获取 CloseableHttpResponse 并检查是否存在 response entity,然后手动读取。
示例代码:手动捕获 response entity
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpClientExample {
public static void main(String[] args) {
String url = "https://example.com/api";
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpGet request = new HttpGet(url);
response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode >= 200 && statusCode < 300) {
HttpEntity entity = response.getEntity();
String responseBody = entity != null ? EntityUtils.toString(entity) : null;
System.out.println("Response Body: " + responseBody);
} else {
// 处理错误响应,获取错误的 response body
HttpEntity entity = response.getEntity();
String errorResponse = entity != null ? EntityUtils.toString(entity) : null;
System.out.println("Error Response Body: " + errorResponse);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
关键点:
- 手动管理
CloseableHttpResponse,即使在出现异常时,也可以手动读取response entity。 - 在错误响应时,通过
response.getEntity()手动获取并读取错误的响应体。
总结:
- Apache HttpClient 抛出的异常,如
HttpResponseException,不会自动包含response entity。如果你想在异常中获取到response entity,最好的做法是使用ResponseHandler或在捕获异常前手动处理响应对象。 - 通过自定义的
ResponseHandler,你可以在请求抛出异常时依然获取到完整的response body。
浙公网安备 33010602011771号