Java使用HttpClient5实现发送HTTP请求

1、HttpClient5 的介绍

HttpClient5 是 Apache HttpComponents 项目中的一个重要组件,它是一个功能齐全且高度可定制的 HTTP 客户端库,专门用于发送 HTTP 请求、处理 HTTP 响应并支持各种 HTTP 协议特性。

以下是对 HttpClient5 的详细介绍:

  • 多协议支持:HttpClient5 支持 HTTP/1.1 和 HTTP/2 协议,特别是 HTTP/2 的多路复用和流优先级等特性,提升了网络请求效率。
  • 连接池管理:内置的连接池机制能提高并发处理性能,减少资源消耗。
  • 多种认证机制:支持 Basic、Digest、NTLM、Kerberos 等多种认证方式,能够处理多种安全场景。
  • Cookie管理:内置 Cookie 管理功能,能够自动处理服务端返回的 Cookie 并在后续请求中使用,模拟浏览器行为。
  • SSL/TLS支持:支持 HTTPS,提供自定义 SSL/TLS 配置,确保通信的安全性。
  • 易于扩展和定制:HttpClient5 的设计高度模块化,用户可以根据需要对连接管理、重定向策略、请求重试策略、代理设置等进行灵活定制。
  • 代理支持:可以轻松配置 HTTP 或 SOCKS 代理,用于跨网络访问和隐私保护。

2、创建 HttpClient5 工具类

通过将常用的方法封装到工具类中,可以避免重复编写相同的代码,从而提高代码的复用性‌。

(1)添加 Maven 依赖

在项目的 pom.xml 配置文件中添加 HttpClient5 依赖。

<!-- HttpClient5 依赖 -->
<dependency><groupId>org.apache.httpcomponents.client5</groupId><artifactId>httpclient5</artifactId><version>5.4</version>
</dependency>

(2)创建工具类

 创建 HttpClientUtil 类(基于 HttpClient5 的 HTTP 请求工具类)。

package com.pjb.consumer.util;import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.util.Timeout;import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;/*** 基于 HttpClient5 的 HTTP 请求工具类* @author pan_junbiao**/
public class HttpClientUtil
{// 超时时间private final static int timeOut = 60000; //60秒/*** 发送 GET 请求并获取响应数据** @param url    请求地址* @param params 请求参数* @return 响应数据字符串*/public static String doGet(String url, Map<String, String> params){HttpGet httpGet = null;                    //请求对象CloseableHttpClient httpClient = null;     //请求客户端CloseableHttpResponse httpResponse = null; //响应对象try{// 1、拼接 URLStringBuffer stringBuffer = new StringBuffer(url);if (params != null && !params.isEmpty()){stringBuffer.append("?");for (Map.Entry<String, String> entry : params.entrySet()){stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");}stringBuffer.deleteCharAt(stringBuffer.length() - 1);}URI targetUri = new URI(stringBuffer.toString());// 2、创建请求对象httpGet = new HttpGet(targetUri);// 请求配置实例(不需要可忽略)RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(Timeout.ofMilliseconds(timeOut)) // 设置连接请求超时时间.setResponseTimeout(Timeout.ofMilliseconds(timeOut)) // 设置响应超时时间.build();httpGet.setConfig(requestConfig);// 3、创建请求客户端httpClient = HttpClients.createDefault();// 4、执行请求操作,并返回响应结果httpResponse = httpClient.execute(httpGet);HttpEntity httpEntity = httpResponse.getEntity();String result = EntityUtils.toString(httpEntity);if (httpResponse.getCode() != HttpStatus.SC_OK){//记录错误日志String errorMessage = String.format("[执行异常]执行GET请求操作失败,状态码:%s,错误信息:%s", httpResponse.getCode(), result);System.out.println(errorMessage);throw new Exception(errorMessage);}return result;} catch (Exception ex){ex.printStackTrace();} finally{//释放资源releaseResource(httpGet, httpClient, httpResponse);}return null;}/*** 发送 POST 请求并获取响应数据** @param url    请求地址* @param params 请求参数* @return 响应数据字符串*/public static String doPost(String url, Map<String, String> params){HttpPost httpPost = null;                  //请求对象CloseableHttpClient httpClient = null;     //请求客户端CloseableHttpResponse httpResponse = null; //响应对象try{// 1、创建 URL 对象URI targetUri = new URI(url);// 2、创建请求对象httpPost = new HttpPost(targetUri);// 请求配置实例(不需要可忽略)RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(Timeout.ofMilliseconds(timeOut)) // 设置连接请求超时时间.setResponseTimeout(Timeout.ofMilliseconds(timeOut)) // 设置响应超时.build();httpPost.setConfig(requestConfig);// 设置请求头httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");// 设置请求格式 multipart/form-datahttpPost.addHeader("Content-type", "multipart/form-data;boundary=" + UUID.randomUUID().toString());httpPost.addHeader("Accept", "*/*");// UTF-8 解决中文乱码httpPost.addHeader("Accept-Encoding", "UTF-8");httpPost.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");// 3、创建请求客户端httpClient = HttpClients.createDefault();// 4、写入请求体List<NameValuePair> paramList = new ArrayList<>();if (params != null && !params.isEmpty()){for (Map.Entry<String, String> entry : params.entrySet()){BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());paramList.add(nameValuePair);}}UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramList, StandardCharsets.UTF_8);httpPost.setEntity(urlEncodedFormEntity);// 5、执行请求操作,并返回响应结果httpResponse = httpClient.execute(httpPost);HttpEntity httpEntity = httpResponse.getEntity();String result = EntityUtils.toString(httpEntity);if (httpResponse.getCode() != HttpStatus.SC_OK){//记录错误日志String errorMessage = String.format("[执行异常]执行POST请求操作失败,状态码:%s,错误信息:%s", httpResponse.getCode(), result);System.out.println(errorMessage);throw new Exception(errorMessage);}return result;} catch (Exception ex){ex.printStackTrace();} finally{//释放资源releaseResource(httpPost, httpClient, httpResponse);}return null;}/*** 发送 JSON 格式的 POST 请求并获取响应数据** @param url       请求地址* @param jsonParam JSON格式的请求参数* @return 响应数据字符串*/public static String doJsonPost(String url, String jsonParam){HttpPost httpPost = null;                  //请求对象CloseableHttpClient httpClient = null;     //请求客户端CloseableHttpResponse httpResponse = null; //响应对象try{// 1、创建 URL 对象URI targetUri = new URI(url);// 2、创建请求对象httpPost = new HttpPost(targetUri);// 请求配置实例(不需要可忽略)RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(Timeout.ofMilliseconds(timeOut)) // 设置连接请求超时时间.setResponseTimeout(Timeout.ofMilliseconds(timeOut)) // 设置响应超时.build();httpPost.setConfig(requestConfig);// 设置请求头httpPost.addHeader("Content-Type", "application/json");httpPost.addHeader("Accept-Encoding", "UTF-8");// 3、创建请求客户端httpClient = HttpClients.createDefault();// 3、写入请求体StringEntity entity = new StringEntity(jsonParam, StandardCharsets.UTF_8);httpPost.setEntity(entity);// 4、执行请求操作,并返回响应结果httpResponse = httpClient.execute(httpPost);HttpEntity httpEntity = httpResponse.getEntity();String result = EntityUtils.toString(httpEntity);if (httpResponse.getCode() != HttpStatus.SC_OK){//记录错误日志String errorMessage = String.format("[执行异常]执行POST请求操作失败,状态码:%s,错误信息:%s", httpResponse.getCode(), result);System.out.println(errorMessage);throw new Exception(errorMessage);}return result;} catch (Exception ex){ex.printStackTrace();} finally{//释放资源releaseResource(httpPost, httpClient, httpResponse);}return null;}/*** 释放资源*/private static void releaseResource(HttpUriRequestBase httpRequest, CloseableHttpClient httpClient, CloseableHttpResponse httpResponse){if (httpRequest != null){try{httpRequest.reset();} catch (Exception e){System.out.println("关闭请求对象失败");}}if (httpClient != null){try{httpClient.close();} catch (IOException e){System.out.println("关闭请求客户端失败");}}if (httpResponse != null){try{httpResponse.close();} catch (IOException e){System.out.println("关闭响应对象失败");}}}
}

3、综合实例

【实例】实现用户信息的查询、新增、修改、删除接口,并使用 HttpClient5 实现接口的请求。

(1)在 controller 层,创建用户信息控制器类,实现查询、新增、修改、删除接口。

package com.pjb.business.controller;import com.pjb.business.entity.UserInfo;
import com.pjb.business.exception.ApiResponseException;
import com.pjb.business.model.ApiModel.ApiResponseCode;
import com.pjb.business.model.ApiModel.ApiResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;/*** 用户信息控制器类* @author pan_junbiao**/
@RestController
@RequestMapping("/user")
@Api(description = "用户信息控制器")
public class UserController
{/*** 查询用户信息*/@ApiOperation(value = "查询用户信息")@RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)public ApiResponseResult<UserInfo> getUserInfo(Long userId){if (userId <= 0){//使用:全局异常处理throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);}UserInfo userInfo = new UserInfo();userInfo.setUserId(userId);userInfo.setUserName("pan_junbiao的博客");userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");//使用:统一返回值return new ApiResponseResult(ApiResponseCode.SUCCESS, userInfo);}/*** 新增用户信息*/@ApiOperation(value = "新增用户信息")@RequestMapping(value = "/addUserInfo", method = RequestMethod.POST)public ApiResponseResult<Boolean> addUserInfo(@RequestBody UserInfo userInfo){if (userInfo == null || userInfo.getUserName() == null || userInfo.getUserName().length() == 0){//使用:全局异常处理throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);}//使用:统一返回值return new ApiResponseResult(ApiResponseCode.SUCCESS, true);}/*** 修改用户信息*/@ApiOperation(value = "修改用户信息")@RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)public ApiResponseResult<Boolean> updateUserInfo(@RequestBody UserInfo userInfo){if (userInfo == null && userInfo.getUserId() <= 0){//使用:全局异常处理throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);}//使用:统一返回值return new ApiResponseResult(ApiResponseCode.SUCCESS, true);}/*** 删除用户信息*/@ApiOperation(value = "删除用户信息")@RequestMapping(value = "/deleteUserInfo", method = RequestMethod.POST)public ApiResponseResult<Boolean> deleteUserInfo(Long userId){if (userId <= 0){//使用:全局异常处理throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);}//使用:统一返回值return new ApiResponseResult(ApiResponseCode.SUCCESS, true);}
}

(2)使用 HttpClient5 发送 Get 请求,查询用户信息。

/*** 使用 HttpClient5 发送 Get 请求,查询用户信息*/
@Test
public void getUserInfo()
{//请求地址String url = "http://localhost:8085/user/getUserInfo";//请求参数Map<String, String> params = new HashMap<>();params.put("userId", "1");//发送 HTTP 的 Get 请求(核心代码)String httpResult = HttpClientUtil.doGet(url, params);//反序列化JSON结果ApiResponseResult<UserInfo> responseResult = JacksonUtil.getJsonToGenericityBean(httpResult, ApiResponseResult.class, UserInfo.class);UserInfo userInfo = responseResult.getData();System.out.println("响应JSON结果:" + httpResult);System.out.println("响应结果编码:" + responseResult.getCode());System.out.println("响应结果信息:" + responseResult.getMessage());System.out.println("用户编号:" + userInfo.getUserId());System.out.println("用户名称:" + userInfo.getUserName());System.out.println("博客信息:" + userInfo.getBlogName());System.out.println("博客地址:" + userInfo.getBlogUrl());
}

执行结果:

(3)使用 HttpClient5 发送 JSON 格式的 POST 请求,新增用户信息。

/*** 使用 HttpClient5 发送 JSON 格式的 POST 请求,新增用户信息*/
@Test
public void addUserInfo()
{//请求地址String url = "http://localhost:8085/user/addUserInfo";//请求参数UserInfo userInfo = new UserInfo();userInfo.setUserId(2L);userInfo.setUserName("pan_junbiao的博客");userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");String json = JacksonUtil.getBeanToJson(userInfo);//发送 JSON 格式的 POST 请求(核心代码)String httpResult = HttpClientUtil.doJsonPost(url, json);System.out.println("响应结果:" + httpResult);
}

执行结果:

响应结果:{"code":200000,"message":"操作成功","data":true}

(4)使用 HttpClient5 发送 POST 请求,删除用户信息。

/*** 使用 HttpClient5 发送 POST 请求,删除用户信息*/
@Test
public void deleteUserInfo()
{//请求地址String url = "http://localhost:8085/user/deleteUserInfo";//请求参数Map<String, String> params = new HashMap<>();params.put("userId","3");//发送 HTTP 的 POST 请求(核心代码)String httpResult = HttpClientUtil.doPost(url, params);System.out.println("响应结果:" + httpResult);
}

执行结果:

响应结果:{"code":200000,"message":"操作成功","data":true}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

部署Qwen2.5-7b大模型详解

部署Qwen2.5-7b大模型详解 本文参考教程&#xff1a;https://qwen.readthedocs.io/en/latest/getting_started/quickstart.html 下载模型 https://modelscope.cn/organization/qwen 搜索 qwen2.5-7b 可以看到它提供了六个模型&#xff0c;以满足不同的需求&#xff0c;从下…

【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

【MATLAB代码,带TDOA数据导入】TDOA三维空间的位置(1主锚点、3副锚点),多个时间点、输出位置的坐标

TDOA介绍 TDOA&#xff08;到达时间差&#xff09;是一种用于定位和跟踪信号源的技术&#xff0c;常用于无线通信、导航和雷达系统。它通过测量信号到达不同接收器的时间差&#xff0c;来计算信号源的位置。 基本原理 TDOA的基本原理是利用多个接收器&#xff08;或锚点&…

Power BI - 设置Waterfall Chart第一个Pillar的颜色

1.简单介绍 有的用户可能会单独设置Column Chart&#xff08;条形图&#xff09;的第一个柱子的颜色&#xff0c;如下图所示&#xff0c; 这种其实可以通过Column Chart的Conditional formating进行设置&#xff0c; - SWICH SELECTEDVALUE 或者也可以直接对单独的Column进行…

用户界面设计:视觉美学与交互逻辑的融合

1、什么是用户界面 用户界面&#xff08;UI&#xff09;是人与机器之间沟通的桥梁&#xff0c;同时也是用户体验&#xff08;UX&#xff09;的重要组成部分。用户界面设计包括两个核心要素&#xff1a;视觉设计&#xff08;即产品的外观和感觉&#xff09;和交互设计&#xff…

CSS 入门

1. CSS 1.1 概念 CSS&#xff08;Cascading Style Sheet&#xff09;&#xff0c;层叠样式表&#xff0c;用于控制页面的样式 CSS 能够对网页中元素位置的排版进行像素级精确控制&#xff0c;实现美化页面的效果&#xff0c;能够做到页面的样式和结构分离&#xff08;类似于…

【数字图像处理】第5章 图像空域增强方法

上理考研周导师的哔哩哔哩频道 我在频道里讲课哦 目录 5.1 图像噪声 相关概念 ①图像噪声的产生 ② 图像噪声分类 ③ 图像噪声特点 5.2 图像增强方法分类 ①图像增强概念 ②图像增强目的 ③图像增强技术方法: 5.3 基于灰度变换的图像增强 1. 概述: 2. 灰度变换…

十大云手机排行榜:哪个云手机更好用?

近些年&#xff0c;市场上涌现出许多云手机产品&#xff0c;不同产品适合的应用场景也各不相同。在选用云手机之前&#xff0c;企业和个人用户需要了解它们的功能、特点以及适用的场景。本文将对当前主流的云手机进行对比&#xff0c;帮助大家挑选出最适合的云手机产品。 1. 红…

【数据结构与算法】之链表详解

链表是一种常用的数据结构&#xff0c;它是一种线性数据结构&#xff0c;但与数组不同&#xff0c;它并非连续存储数据&#xff0c;而是通过指针将数据节点连接起来。每个节点都包含数据域和指向下一个节点的指针域。这种结构赋予链表独特的优势和局限性&#xff0c;使其在某些…

九种排序,一次满足

我们在算法题进行练习提升时&#xff0c;经常会看到题目要求数据从大到小输出&#xff0c;从小到大输出&#xff0c;前一半从小到大输出&#xff0c;后一半从大到小输出等&#xff0c;那么这时候就需要用到排序算法&#xff0c;通过排序算法将数据按照一定的顺序进行排序。本文…

解决PyCharm 2023 Python Packages列表为空

原因是因为没有设置镜像源 展开 > 之后&#xff0c;这里 点击齿轮 添加一个阿里云的源 最后还需要点击刷新 可以选择下面的任意一个国内镜像源&#xff1a; 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/…

设计模式之-策略模式配合枚举

1、定义枚举接收不同的参数使用不同的handler, 2、定义个handerl接口&#xff0c;统一方法处理&#xff0c;每个handler实现该接口 public interface IMethodHandler<T, R> {/*** 处理统一入口** param req*/R process(T req); } java3、定义一个简单工厂统一处理 Comp…

送给正在入行的小白:最全最有用的网络安全学习路线已经安排上了,零基础入门到精通,收藏这一篇就够了

在这个圈子技术门类中&#xff0c;工作岗位主要有以下三个方向&#xff1a; 安全研发安全研究&#xff1a;二进制方向安全研究&#xff1a;网络渗透方向 下面逐一说明一下。 第一个方向&#xff1a;安全研发 你可以把网络安全理解成电商行业、教育行业等其他行业一样&#xf…

k8s 1.28.2 集群部署 harbor v2.11.1 接入 MinIO 对象存储

文章目录 [toc]提前准备什么是 HarborHarbor 架构描述Harbor 安装的先决条件硬件资源软件依赖端口依赖 Harbor 在 k8s 的高可用Harbor 部署Helm 编排YAML 编排创建 namespace导入镜像部署 Redis部署 PostgreSQL部署 Harbor core部署 Harbor trivy部署 Harbor jobservice部署 Ha…

RTSP流图片采样助手(yolov5)

在监控和视频分析领域&#xff0c;实时采样视频流中的图像数据是十分重要的。本文将介绍一个基于Python和Tkinter构建的RTSP流图片采样助手的设计与实现&#xff0c;旨在简化RTSP流的采样过程&#xff0c;并支持根据用户定义的特殊标签进行筛选。 项目概述 该项目的主要功能包…

Data+AI下的数据湖和湖仓一体发展史

DataAI下的数据湖和湖仓一体发展史 前言数据湖的“前世今生”AI时代的救星&#xff1a;湖仓一体湖仓一体实践演进未来趋势&#xff1a;智能化、实时化结语 前言 数据湖&#xff1f;湖仓一体&#xff1f;这是什么高科技新名词&#xff1f; 别急&#xff0c;我们慢慢聊。想象一…

ICT产业新征程:深度融合与高质量发展

在信息时代的浪潮中&#xff0c;每一场关于技术革新与产业融合的盛会都闪耀着智慧的光芒&#xff0c;引领着未来的方向。9月25日&#xff0c;北京国家会议中心内&#xff0c;一场聚焦全球信息通信业的顶级盛事——第32届“国际信息通信展”&#xff08;PT展&#xff09;隆重拉开…

Maven基于构建阶段分析多余的依赖

基于构建阶段 test compile 实现依赖分析 执行maven 命令: mvn dependency:analyze 关注:Maven-dependency-plugin 分析结果: [INFO] --- maven-dependency-plugin:2.10:analyze (default-cli) impl --- 配置依赖未使用的依赖项&#xff1a; [INFO] --- maven-dependency-…

Linux基础项目开发day2:量产工具——输入系统

文章目录 前言一、数据结构抽象1、数据本身2、设备本身3、input_manager.h 二、触摸屏编程1、touchscreen.c 三、触摸屏单元测试1、touchscreen.c2、上机测试 四、网络编程netiput.c 五、网络单元测试1、netiput.c2、client.c3、上机测试 六、输入系统的框架1、框架思路2、inpu…

数据库设计与开发—初识SQLite与DbGate

一、SQLite与DbGate简介 &#xff08;一&#xff09;SQLite[1][3] SQLite 是一个部署最广泛、用 C 语言编写的数据库引擎&#xff0c;属于嵌入式数据库&#xff0c;其作为库被软件开发人员嵌入到应用程序中。 SQLite 的设计允许在不安装数据库管理系统或不需要数据库管理员的情…