HttpClient工具类编写

HttpClient

介绍

HttpClient是Apache Jakarta Common下的一个子项目,它提供了一个高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包。它支持HTTP协议最新的版本和建议,并实现了Http1.0和Http1.1协议。

HttpClient具有可扩展的面向对象的结构,实现了Http全部的方法,包括GET、POST、PUT、DELETE、HEAD、OPTIONS以及TRACE。它支持HTTPS协议,并允许通过Http代理建立透明的连接,以及利用CONNECT方法建立隧道的https连接。此外,它还支持多种认证方案,如Basic、Digest、NTLMv1、NTLMv2、NTLM2 Session以及SNPNEGO/Kerberos,并允许使用插件式的自定义认证方案。

在项目中,HttpClient的使用场景广泛,如爬虫、多系统之间的接口交互等。在分布式项目中,前端系统需要调用后台的数据并初始化时,可以使用HttpClient进行通信。

在使用HttpClient时,通常需要导入相关的依赖库,并根据具体需求配置HttpClient的行为,如设置连接超时、读取超时等。然后,可以使用HttpClient发送GET、POST等请求,并处理返回的响应。

在SpringBoot后端项目开发时,什么时候需要HttpClient?

调用第三方服务的时候

构造HTTP请求

HttpClient的maven坐标:

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>

其实阿里云oss已经依赖了httpclient,所以无需再引入这个包

HttpClient的核心API:

  • HttpClient(HttpClient对象接口):Http客户端对象类型,使用该类型对象可发起Http请求。

  • HttpClients:可认为是构建器,可创建HttpClient对象。

  • CloseableHttpClient(HttpClient对象实现类):实现类,实现了HttpClient接口。

  • HttpGet(Http请求对象):Get方式请求类型。

  • HttpPost(Http请求对象):Post方式请求类型。

HttpClient发送请求步骤:

  • 创建HttpClient对象

  • 创建Http请求对象

  • 调用HttpClient的execute方法发送请求

 GET请求

实现步骤:

  1. 创建HttpClient对象

  2. 创建请求对象

  3. 发送请求,接受响应结果

  4. 解析结果

  5. 关闭资源

package com.sky.test;
​
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 org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
​
@SpringBootTest
public class HttpClientTest {
​/*** 测试通过httpclient发送GET方式的请求*/@Testpublic void testGET() throws Exception{//创建httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();
​//创建请求对象HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");
​//发送请求,接受响应结果CloseableHttpResponse response = httpClient.execute(httpGet);
​//获取服务端返回的状态码int statusCode = response.getStatusLine().getStatusCode();System.out.println("服务端返回的状态码为:" + statusCode);
​HttpEntity entity = response.getEntity();String body = EntityUtils.toString(entity);System.out.println("服务端返回的数据为:" + body);
​//关闭资源response.close();httpClient.close();}
}

在访问http://localhost:8080/user/shop/status请求时,需要提前启动项目。

注意:

  • 创建HttpClient对象需要调用HttpClients.createDefault()方法,创建一个CloseableHttpClient对象
  • 创建请求对象:HttpGet httpGet = new HttpGet("请求url");
  • 利用HttpCliet对象执行execute请求对象,得到响应结果response:CloseableHttpResponse response = httpClient.execute(httpGet);
  • 解析响应结果:

            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("服务端返回的状态码为:" + statusCode);

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);
            System.out.println("服务端返回的数据为:" + body);

  • 关闭资源:

        response.close();
        httpClient.close();

Post请求

在HttpClientTest中添加POST方式请求方法,相比GET请求来说,POST请求若携带参数需要封装请求体对象,并将该对象设置在请求对象中。

实现步骤:

  1. 创建HttpClient对象

  2. 创建请求对象

  3. 发送请求,接收响应结果

  4. 解析响应结果

  5. 关闭资源

	/*** 测试通过httpclient发送POST方式的请求*/@Testpublic void testPOST() throws Exception{// 创建httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();//创建请求对象HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");JSONObject jsonObject = new JSONObject();jsonObject.put("username","admin");jsonObject.put("password","123456");StringEntity entity = new StringEntity(jsonObject.toString());//指定请求编码方式entity.setContentEncoding("utf-8");//数据格式entity.setContentType("application/json");httpPost.setEntity(entity);//发送请求CloseableHttpResponse response = httpClient.execute(httpPost);//解析返回结果int statusCode = response.getStatusLine().getStatusCode();System.out.println("响应码为:" + statusCode);HttpEntity entity1 = response.getEntity();String body = EntityUtils.toString(entity1);System.out.println("响应数据为:" + body);//关闭资源response.close();httpClient.close();}

HttpPost请求对象需要利用setEntity方法补充json格式的请求体数据。

1、打包Json数据

       JSONObject jsonObject = new JSONObject();
        jsonObject.put("username","admin");
        jsonObject.put("password","123456");

        StringEntity entity = new StringEntity(jsonObject.toString());

2、设置请求编码方式和数据格式

        //指定请求编码方式
        entity.setContentEncoding("utf-8");
        //数据格式
        entity.setContentType("application/json");

3、setEntity打包Json数据

httpPost.setEntity(entity);

4、利用HttpClient对象的execute方法发送请求
        CloseableHttpResponse response = httpClient.execute(httpPost);

编写HttpClient工具类

/*** Http工具类*/
public class HttpClientUtil {static final  int TIMEOUT_MSEC = 5 * 1000;/*** 发送GET方式请求* @param url* @param paramMap* @return*/public static String doGet(String url,Map<String,String> paramMap){// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();String result = "";CloseableHttpResponse response = null;try{URIBuilder builder = new URIBuilder(url);if(paramMap != null){for (String key : paramMap.keySet()) {builder.addParameter(key,paramMap.get(key));}}URI uri = builder.build();//创建GET请求HttpGet httpGet = new HttpGet(uri);//发送请求response = httpClient.execute(httpGet);//判断响应状态if(response.getStatusLine().getStatusCode() == 200){result = EntityUtils.toString(response.getEntity(),"UTF-8");}}catch (Exception e){e.printStackTrace();}finally {try {response.close();httpClient.close();} catch (IOException e) {e.printStackTrace();}}return result;}/*** 发送POST方式请求* @param url* @param paramMap* @return* @throws IOException*/public static String doPost(String url, Map<String, String> paramMap) throws IOException {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建参数列表if (paramMap != null) {List<NameValuePair> paramList = new ArrayList();for (Map.Entry<String, String> param : paramMap.entrySet()) {paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));}// 模拟表单UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);httpPost.setEntity(entity);}httpPost.setConfig(builderRequestConfig());// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "UTF-8");} catch (Exception e) {throw e;} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}/*** 发送POST方式请求* @param url* @param paramMap* @return* @throws IOException*/public static String doPost4Json(String url, Map<String, String> paramMap) throws IOException {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);if (paramMap != null) {//构造json格式数据JSONObject jsonObject = new JSONObject();for (Map.Entry<String, String> param : paramMap.entrySet()) {jsonObject.put(param.getKey(),param.getValue());}StringEntity entity = new StringEntity(jsonObject.toString(),"utf-8");//设置请求编码entity.setContentEncoding("utf-8");//设置数据类型entity.setContentType("application/json");httpPost.setEntity(entity);}httpPost.setConfig(builderRequestConfig());// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "UTF-8");} catch (Exception e) {throw e;} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}private static RequestConfig builderRequestConfig() {return RequestConfig.custom().setConnectTimeout(TIMEOUT_MSEC).setConnectionRequestTimeout(TIMEOUT_MSEC).setSocketTimeout(TIMEOUT_MSEC).build();}}

1. doGet(String url, Map<String,String> paramMap)

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象,键和值都是 String 类型。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP GET 请求。它首先创建一个 HttpClient 对象,然后使用 URIBuilder 来添加请求参数。如果响应状态码为200,它将响应正文转换为字符串并返回。

2. doPost(String url, Map<String, String> paramMap) throws IOException

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP POST 请求,请求参数以表单形式发送。它创建一个 HttpPost 对象,并将参数作为 UrlEncodedFormEntity 设置到请求中。然后发送请求并返回响应正文。

3. doPost4Json(String url, Map<String, String> paramMap) throws IOException

输入:

  • url: 要请求的URL地址。
  • paramMap: 一个包含请求参数的 Map 对象。

输出:

  • 返回一个 String 类型的结果,表示 HTTP 响应的正文内容。

功能:

  • 该方法用于构造一个 HTTP POST 请求,请求参数以 JSON 格式发送。它创建一个 HttpPost 对象,并将参数构造为 JSON 对象,然后设置到请求的 StringEntity 中。请求的 Content-Type 被设置为 application/json,然后发送请求并返回响应正文。

4. builderRequestConfig()

输入:

  • 无。

输出:

  • 返回一个 RequestConfig 对象。

功能:

  • 这是一个私有方法,用于构建 RequestConfig 对象,它设置了连接超时、请求超时和套接字超时的默认值。

使用HttpClient工具类

以下是三个示例,展示如何使用 HttpClientUtil 类提供的前三个方法构造 HTTP 请求,并分析响应结果:

示例 1: 使用 doGet 方法发送 GET 请求

假设我们想要从 http://example.com/api/data 获取一些数据,并且有一些查询参数。

import java.util.HashMap;
import java.util.Map;public class HttpClientUtilExample {public static void main(String[] args) {// 准备请求参数Map<String, String> params = new HashMap<>();params.put("param1", "value1");params.put("param2", "value2");// 发送 GET 请求String result = HttpClientUtil.doGet("http://example.com/api/data", params);// 分析响应结果if (result != null && !result.isEmpty()) {System.out.println("Response: " + result);// 这里可以根据需要解析 JSON 或 XML 响应体} else {System.out.println("No response received or error occurred.");}}
}

示例 2: 使用 doPost 方法发送表单 POST 请求

假设我们想要向 http://example.com/api/login 发送登录请求。

public class HttpClientUtilExample {public static void main(String[] args) {// 准备登录参数Map<String, String> params = new HashMap<>();params.put("username", "user123");params.put("password", "pass123");try {// 发送 POST 请求String result = HttpClientUtil.doPost("http://example.com/api/login", params);// 分析响应结果if (result != null && !result.isEmpty()) {System.out.println("Login Response: " + result);// 根据响应内容判断登录是否成功} else {System.out.println("Login failed or error occurred.");}} catch (IOException e) {e.printStackTrace();System.out.println("An error occurred during the POST request.");}}
}

示例 3: 使用 doPost4Json 方法发送 JSON POST 请求

假设我们想要向 http://example.com/api/register 发送注册请求,并且请求体是 JSON 格式。

public class HttpClientUtilExample {public static void main(String[] args) {// 准备登录参数Map<String, String> params = new HashMap<>();params.put("username", "user123");params.put("password", "pass123");try {// 发送 POST 请求String result = HttpClientUtil.doPost("http://example.com/api/login", params);// 分析响应结果if (result != null && !result.isEmpty()) {System.out.println("Login Response: " + result);// 根据响应内容判断登录是否成功} else {System.out.println("Login failed or error occurred.");}} catch (IOException e) {e.printStackTrace();System.out.println("An error occurred during the POST request.");}}
}

在每个示例中,我们首先创建了一个包含请求参数的 Map 对象,然后调用相应的方法发送请求。请求完成后,我们检查响应结果是否为 null 或者为空,如果不是,则打印出响应内容。在处理 POST 请求的示例中,我们还捕获了可能发生的 IOException

doPostdoPost4JsonHttpClientUtil 类中定义的两个发送 POST 请求的方法,它们的主要区别在于发送请求体的格式不同

doPost 方法:

  • 请求体格式doPost 方法发送的请求体是标准的表单格式(application/x-www-form-urlencoded)。
  • 参数构建:它使用 UrlEncodedFormEntity 来构建请求体,这适用于传统的表单提交,其中键值对被编码为字符串,并用 & 符号分隔。
  • 适用场景:当后端服务期望接收表单数据时,使用此方法。

doPost4Json 方法:

  • 请求体格式doPost4Json 方法发送的请求体是 JSON 格式(application/json)。
  • 参数构建:它使用 JSONObject 来构建请求体,然后将 JSON 对象转换为字符串,并设置到 StringEntity 中。
  • 适用场景:当后端服务期望接收 JSON 格式的请求体时,使用此方法。

代码层面的区别:

  • doPost 方法中,参数是通过遍历 paramMap 并使用 BasicNameValuePair 对象添加到 paramList 中,然后构建 UrlEncodedFormEntity 对象。
  • doPost4Json 方法中,参数是通过遍历 paramMap 并使用 JSONObject 的 put 方法添加到 JSON 对象中,然后构建 StringEntity 对象,并设置正确的 Content-Encoding 和 Content-Type

实际使用时的考虑因素:

  • 内容类型:客户端需要根据服务器端的期望来设置正确的 Content-Type
  • 编码:对于 JSON 请求体,需要确保字符编码正确设置为 UTF-8,以避免编码问题。
  • API 约定:不同的 API 可能对请求体的格式有不同的要求,选择正确的方法来满足这些要求是非常重要的。

在实际应用中,选择使用 doPost 还是 doPost4Json 取决于你要与之交互的 API 的具体要求。通常,现代的 RESTful API 更倾向于使用 JSON 格式,因为它结构化更好、更易于解析。然而,一些旧的或特定的系统可能仍然使用传统的表单数据格式。

传统的表单格式,通常指的是 application/x-www-form-urlencoded 格式,这是一种用于 HTTP 请求的编码方式,特别是用于表单数据的提交。在 Web 开发中,这是最常见的数据提交方式之一。

特点:

  1. 键值对:数据由键值对组成,其中键(key)和值(value)由等号(=)连接。
  2. 编码:所有键和值都必须进行百分比编码(也称为 URL 编码),以确保特殊字符可以安全地传输。
  3. 分隔:键值对之间通过和号(&)分隔。
  4. 兼容性:几乎所有的服务器端语言和框架都支持这种格式,因此它具有很好的兼容性。

示例:

假设有一个表单,包含用户名和密码字段,用户填写后提交到服务器:

<form action="/submit" method="post"> <input type="text" name="username" value="user123"> <input type="password" name="password" value="pass123"> <input type="submit" value="Submit"> </form>

当用户提交这个表单时,浏览器会将数据编码成以下格式:

username=user123&password=pass123

HTTP 请求示例:

POST /submit HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded username=user123&password=pass123

与传统表单格式相比的 JSON:

  • 结构:JSON 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
  • 格式:JSON 数据是自描述的,由键值对组成,键是字符串,值可以是字符串、数字、数组、布尔值或其他 JSON 对象。
  • 数据类型:JSON 支持更丰富的数据类型,如数组和嵌套对象。
  • 使用场景:JSON 通常用于 API 通信,特别是 RESTful API。

JSON 请求示例:

POST /api/register HTTP/1.1 Host: example.com Content-Type: application/json; charset=utf-8 { "username": "user123", "password": "pass123" }

在现代 Web 应用和 API 开发中,JSON 格式因其结构化和易于处理的特点而变得越来越流行,尤其是在需要传输复杂数据结构时。然而,传统的表单格式由于其简单性和广泛的支持,仍然在特定场景下被广泛使用。

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

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

相关文章

《HCIP-openEuler实验指导手册》1.6 Apache静态资源配置

知识点 常用用途&#xff1a; 软件仓库镜像及提供下载服务&#xff1a; 配置步骤 删除网站主目录中的文件&#xff08;本实验机目录为/home/source ip为192.168.12.137 端口为81&#xff09; cd /home/source rm -rf *在主目录中新建6个文件夹如下图 mkdir test{1..6}新建…

一 SSM 整合理解

SSM整合理解 一 SSM整合什么 ​ 以spring框架为基础&#xff0c;整合springmvc&#xff0c;mybatis框架&#xff0c;以更好的开发。 ​ spring管理一切组件&#xff0c;为开发更好的解耦&#xff0c;以及提供框架的组件&#xff0c;如aop&#xff0c;tx。springmvc是表述层框…

Bus Hound数据不完整

Bus Hound用来抓USB数据很方便&#xff0c;最近用Bus Hound来抓HID描述符的时候发现总是数据不全&#xff0c;比如我抓到的&#xff1a; HID描述符应该是在81 06 00 22 00 00 7f 00之后的IN传输里面&#xff0c;也就是&#xff1a; 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00…

windows如何安装MySQL(详)

MySQL在Windows上的安装和配置 官网&#xff1a;www.mysql.com 下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions) window系统 安装包&#xff08;Windows (x86, 64-bit), MSI Installer&#xff09; 压缩包&#xff08;Windows (x86, 64…

Mac NTFS磁盘读写工具选择:Tuxera还是Paragon?

在Mac上使用NTFS磁盘时&#xff0c;选择一款合适的读写工具至关重要。Tuxera和Paragon作为两款备受推崇的Mac NTFS磁盘读写工具&#xff0c;都能够帮助用户轻松地实现NTFS格式的读写。那么&#xff0c;面对这两款功能强大的工具&#xff0c;我们应该如何选择呢&#xff1f;本文…

Python脚本实现PC端大麦网自动购票(Selenium自动化测试工具)

文章目录 Selenium 简介Selenium webdriver 文档chromedriver&#xff08;谷歌浏览器驱动&#xff09;chromedriver 下载配置环境变量 大麦网购票脚本网页 dom 元素 启用远程调试&#xff08;操作已打开的窗口&#xff09; Selenium 简介 Selenium 是一个用于自动化测试的工具…

Linux多进程(二)进程通信方式三 共享内存

共享内存提供了一个在多个进程间共享数据的方式&#xff0c;它们可以直接访问同一块内存区域&#xff0c;因此比使用管道或消息队列等通信机制更高效。在多进程程序中&#xff0c;共享内存通常与信号量一起使用&#xff0c;以确保对共享内存的访问是线程安全的。 一、打开/创建…

《高效的机器学习团队:机器学习从业者的最佳实践》

书籍&#xff1a;Effective Machine Learning Teams: Best Practices for ML Practitioners 作者&#xff1a;David Tan&#xff0c;Ada Leung&#xff0c;David Colls 出版&#xff1a;OReilly Media 书籍下载-《高效的机器学习团队&#xff1a;机器学习从业者的最佳实践》…

架构师系列- 定时任务(二)- Quartz框架

quartz特点 Quartz是一个优秀的任务调度框架&#xff0c; 具有以下特点 强大的调度功能&#xff0c;例如支持丰富多样的调度方法&#xff0c;可以满足各种常规及特殊需求&#xff1b;负载均衡高可用 quartz 架构体系 Quartz 设计有四个核心类&#xff0c;分别是Scheduler(调度…

Access2019直接将数据导入SQL Server数据库中,再直接链接回来

Access2019 的数据表等&#xff0c;除了通过 SSMA 导入数据库外&#xff0c;还可以利用access2019 自身的外部数据导出功能来达到目的。本文将详细介绍这一操作过程。 一、命令行操作阶段 1.以SA这一超级用户登录SQL Server&#xff0c;创建一个数据库&#xff0c;例如“个人…

[华为od]给你一串未加密的字符串 str 100

题目&#xff1a; 题目描述&#xff1a; 给你一串未加密的字符串 str&#xff0c;通过对字符串的每一个字母进行改变来实现加密&#xff0c;加密方式 是在每一个字母str[i]偏移特定数组元素a[i]的量&#xff0c;数组a前三位已经赋值&#xff1a; a[0]1,a[1]2,a[2]4。 当 i…

Ansible一键部署zabbix+grafana+agent

目录 IP地址规划ansible安装分开部署安装zabbix-mysql安装zabbix-server安装zabbix-agent安装zabbix-grafana 一键部署自动发现 IP地址规划 名字地址主要安装软件ansible-server192.168.40.137zabbix-server、ansible、zabbix-mysqlzabbix-agent1192.168.40.138zabbix-agentza…