首页 > 其他分享 >使用 Apatch HttpRequest 的情况下,使用 HttpRequest.execute 方法, 假如该方法抛出了异常,应该从哪个异常中获取到responseEntity String ?我

使用 Apatch HttpRequest 的情况下,使用 HttpRequest.execute 方法, 假如该方法抛出了异常,应该从哪个异常中获取到responseEntity String ?我

时间:2024-10-08 14:23:34浏览次数:7  
标签:HttpRequest execute entity org apache import 异常 response

在使用 Apache HttpClient 时,如果调用 HttpRequest.execute() 抛出了异常,通常情况下,异常不会直接包含完整的 response entity。特别是当服务器返回错误响应(如 4xx 或 5xx 状态码)时,execute() 方法可能抛出各种类型的 IOExceptionHttpResponseException,但这些异常并不一定会携带完整的 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();
            }
        }
    }
}

关键点说明:

  1. ResponseHandler:通过自定义的 ResponseHandler,你可以在错误响应(如 4xx 或 5xx)时,捕获并读取 response entity,而不是让 execute() 方法直接抛出异常。
  2. 错误处理:在 ResponseHandler 中处理状态码大于等于 400 的响应,并将 response entity 转换为 String,即使抛出异常,也可以从异常中获取到响应体。
  3. 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

标签:HttpRequest,execute,entity,org,apache,import,异常,response
From: https://www.cnblogs.com/gongchengship/p/18451555

相关文章

  • 【STL详解】STL标准模板库入门 | STL版本 | STL六大组件 | STL优点 | 常用STL容器vect
    目录1、概述1.1、C++标准库1.2、Boost开源库2、STL版本2.1、HP原始版本2.2、P.J.实现版本2.3、RW实现版本2.4、SGI实现版本2.5、STLport实现版本3、STL的六大组件3.1、STL六大组件构成3.2、六大组件的交互关系4、STL优点5、STL常用容器vector、list......
  • mysql数据库连接异常问题(总结)
    针对你提到的多种数据库连接问题,下面进行总结和建议,以避免未来再次遇到相同的问题:1.连接超时(AnattemptbyaclienttocheckoutaConnectionhastimedout)原因:网络不稳定数据源配置参数异常解决方案:优化网络环境:检查网络延迟和丢包率。考虑使用更稳定的网络......
  • Python语言中程序运行错误和异常处理
    '''Python捕获异常:一旦发生异常,程序就会终止,这是非常糟糕的事情,这种糟糕体现在两方面1.即便发生了异常,业务上可以忽略它,那么程序应当继续执行2.程序终止,使得异常的信息没有被保留下来,不利于问题的分析和总结为了提高程序的健壮性和解决问题,可以将异常捕获,根据业务......
  • 程序运行异常: Undefined constant"PAGE
    在使用PbootCMS时,如果遇到“Undefinedconstant'PAGE'”的错误,尤其是在后台自定义表单编辑字段时,这通常是由于PHP版本不兼容导致的问题。具体来说,某些常量或函数可能在较高版本的PHP中不再支持或行为有所变化。解决方法降低PHP版本:将PHP版本从8.0降到7.3。详细步骤检......
  • Python异常处理:让你的代码更稳健的魔法
    引言:你是否曾经在代码中迷失?想象一下,你正在编写一个重要的Python程序,突然间,屏幕上弹出一条错误信息,仿佛一只无形的手将你的努力撕得粉碎。你是否曾经感到无助,甚至想要放弃?根据统计,程序员在开发过程中,约有70%的时间都在处理错误和异常。可见,异常处理不仅是编程的“必修课”,更是......
  • SpringBoot项目使用yml文件链接数据库异常
    SpringBoot使用properties连接数据库时没有出现问题SpringBoot使用yml连接数据库时出现:UnabletoconnecttoRedis并在报错信息中出现:发现是用户或者密码出现问题通过查询知道yml是区分数据类型的,所以如果用户名或者密码是数字的话,就要注意将密码用双引号括起来,将其识别为......
  • 数据库保存异常,参数异常不匹配
    有一个项目,用的是sqllite的数据库。因为版本迭代,数据库字段也在不断地增加当中。最近发生了一个奇怪的异常,保存数据的时候报参数不匹配的错误。后来查找数据库发现了两个问题:问题1:某字段没有新增成功问题2:但是查询的时候,显示该字段是存在的一."altertableaverage_dataadd......
  • [python] 基于PyOD库实现数据异常检测
    PyOD是一个全面且易于使用的Python库,专门用于检测多变量数据中的异常点或离群点。异常点是指那些与大多数数据点显著不同的数据,它们可能表示错误、噪声或潜在的有趣现象。无论是处理小规模项目还是大型数据集,PyOD提供了50多种算法以满足用户的需求。PyOD的特点包括:统一且用户友......
  • Spring MVC 中的日期时间格式校验与异常处理
    个人名片......
  • 【python进阶攻略10】异常、lambda表达式
    异常异常处理是一种艺术,一旦你掌握,会授予你无穷的力量。我将要向你展示我们能处理异常的一些方式。最基本的术语里我们知道了try/except从句。可能触发异常产生的代码会放到try语句块里,而处理异常的代码会在except语句块里实现。这是一个简单的例子:try:file=open(......