当前位置: 首页 > article >正文

[实践总结] 使用Apache HttpClient 4.x进行进行一次Http请求

使用Apache HttpClient 4.x进行进行一次Http请求

依赖

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.7</version>
</dependency>

请求式样

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
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 HttpPostUtils {
    /**
     * @param uri  the request address
     * @param json the request data that must be a JSON string
     * @throws IOException    if HTTP connection can not opened or closed successfully
     * @throws ParseException if response data can not be parsed successfully
     */
    public String retryPostJson(String uri, String json) throws IOException, ParseException {
        if (StringUtils.isAnyBlank(uri, json)) {
            return null;
        }

        // 构建HttpClient
        CloseableHttpClient client = HttpClients.custom().setRetryHandler(new RetryHandler()).build();

        // 构建请求
        HttpPost httpPost = new HttpPost(uri);
        // 设置请求体
        StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        // 设置超时时间
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(5000) // 超5秒还没返回新的可用链接,抛ConnectionPoolTimeoutException。默认值为0,表示无限等待。
                .setConnectTimeout(5000) // 超5秒还没建立链接,抛ConnectTimeoutException。默认值为0,表示无限等待。
                .setSocketTimeout(5000) // 超5秒还没返回数据,抛SocketTimeoutException。默认值为0,表示无限等待。
                .build();
        httpPost.setConfig(config);

        // Response
        CloseableHttpResponse response = null;
        String responseContent = null;
        try {
            response = client.execute(httpPost, HttpClientContext.create());
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name());
            }
        } finally {
            if (response != null) {
                response.close();
            }
            if (client != null) {
                client.close();
            }
        }
        return responseContent;
    }
}

失败重试机制

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;

public class RetryHandler implements HttpRequestRetryHandler {
    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
        if (executionCount >= 2) {
            // 如果已经重试了2次,就放弃
            // Do not retry if over max retry count
            return false;
        }
        if (exception instanceof NoHttpResponseException) {
            // 如果服务器丢掉了连接,那么就重试
            return true;
        }
        if (exception instanceof SSLHandshakeException) {
            // 不要重试SSL握手异常
            return false;
        }
        if (exception instanceof SSLException) {
            // SSL握手异常
            // SSL handshake exception
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {
            // 连接被拒绝
            return false;
        }
        if (exception instanceof InterruptedIOException) {
            // An input or output transfer has been terminated
            // 超时
            return false;
        }
        if (exception instanceof UnknownHostException) {
            // Unknown host 修改代码让不识别主机时重试,实际业务当不识别的时候不应该重试,再次为了演示重试过程,执行会显示retryCount次下面的输出
            // 目标服务器不可达
            System.out.println("不识别主机重试");
            return true;
        }
        if (exception instanceof ConnectException) {
            // Connection refused
            return false;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(context);
        HttpRequest request = clientContext.getRequest();
        if (!(request instanceof HttpEntityEnclosingRequest)) {
            // Retry if the request is considered idempotent
            return true;
        }
        return false;
    }
}

模拟解析返回的Json串

public static List<User> parserJsonToUser() {
    // 模拟返回的Json串
    Map<String, List<String>> map = new HashMap<>();
    map.put("name", Arrays.asList("name1", "name2", "name3"));
    map.put("age", Arrays.asList("11", "23", "23"));
    map.put("num", Arrays.asList("123", "234", "345"));
    String json1 = JsonUtils.toJson(map);
    System.out.println(json1);
    // fastjson
    JSONObject jsonObject = JSON.parseObject(json1, Feature.OrderedField);
    // 返回的属性
    List<String> fields = new ArrayList<>(map.keySet());
    // 几份值
    int size = jsonObject.getJSONArray(fields.get(0)).size();
    List<User> users = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        User user1 = new User();
        for (String field : fields) {
            Object value = jsonObject.getJSONArray(field).get(i);
            ReflectUtils.setFieldValue(user1, field, value);
        }
        users.add(user1);
    }
    System.out.println(users);
    return users;
}

结果
{"num":["123","234","345"],"name":["name1","name2","name3"],"age":["11","23","23"]}
[HttpPostUtils.User(name=name1, age=11, num=123), HttpPostUtils.User(name=name2, age=23, num=234), HttpPostUtils.User(name=name3, age=23, num=345)]

参考

使用Apache HttpClient 4.x进行异常重试

Need 学习消化

二十六、CloseableHttpClient的使用和优化


http://www.kler.cn/news/160450.html

相关文章:

  • [ffmpeg] av_opt_set 解析
  • MongoDB知识总结
  • 【二分答案法】寻找峰值
  • ALPHA开发板烧录工具MfgTool烧写方法
  • Linux系统调试课:网络性能工具总结
  • HCIP考试实验
  • RDMA编程实例rdma_cm API
  • 多传感器融合SLAM在自动驾驶方向的初步探索的记录
  • Gitlab 安装手册
  • 七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置
  • Python:核心知识点整理大全4-笔记
  • C++ IO库
  • Baumer工业相机堡盟工业相机如何通过BGAPISDK将相机图像高速保存到电脑内存(C#)
  • 团建策划信息展示服务预约小程序效果如何
  • 短视频购物系统源码:构建创新购物体验的技术深度解析
  • 【前端设计模式】之观察者模式
  • vue3+ts自定义插件
  • 智能优化算法应用:基于白冠鸡算法无线传感器网络(WSN)覆盖优化 - 附代码
  • Redis key过期删除机制实现分析
  • Docker中安装Oracle10g和oracle增删改查
  • java 操作git
  • Excel 动态拼接表头实现导出
  • easyui实现省市县三级联动
  • 一张图理解接口测试框架
  • 汽车网络安全--ISO\SAE 21434解析(一)
  • 华为OD机试 - 机场航班调度程序(Java JS Python C)
  • 持续集成交付CICD:Jenkins使用GitLab共享库实现自动更新前后端项目质量配置
  • 【Qt】QLineEdit显示输入十六进制,位数不足时按照规则填充显示及每两个字符以空格填充
  • 零基础小白怎么准备蓝桥杯-蓝桥杯竞赛经验分享
  • 【使用uniapp完成微信小程序的图片下载到本机】