HttpClient工具类

HttpClient工具类 1. 前言
在现代软件开发中,HTTP客户端库是与Web服务交互的关键组件。本文将介绍一个功能丰富的HttpClientUtils工具类,它不仅简化了发送HTTP请求的过程&#xff

1. 前言

在现代软件开发中,HTTP 客户端库是与Web 服务交互的关键组件。本文介绍功能丰富的HttpClientUtils工具类。这不仅简化了发送HTTP 请求的过程,还提供了绕过HTTPS 证书验证的能力。这对于调试和测试您的环境特别有用。该工具类基于Apache HttpClient 库构建,结合了Spring 框架的便利性和Lombok 简化代码的特性,旨在提高开发人员效率。

2. 工具类代码

消息:

1. 如果请求体为空,则不要传递null,而是传递一个空字符串。

功能支持:

1.支持http和https协议。

2. 支持GET、POST、PUT、DELETE请求。

3.支持下载图片到本地。

1. 所需依赖:

依赖

groupIdorg.apache.httpcomponents/groupId

artifactIdhttpclient/artifactId

版本4.5.13/版本

/依赖

2、代码:

包com.zjp.demo.utils;

导入lombok.extern.slf4j.Slf4j;

导入org.apache.http.Header。

导入org.apache.http.HeaderIterator。

导入org.apache.http.HttpEntity。

导入org.apache.http.HttpResponse。

导入org.apache.http.client.methods.*。

导入org.apache.http.config.Registry。

导入org.apache.http.config.RegistryBuilder。

导入org.apache.http.conn.socket.ConnectionSocketFactory。

导入org.apache.http.conn.socket.PlainConnectionSocketFactory。

导入org.apache.http.conn.ssl.NoopHostnameVerifier。

导入org.apache.http.conn.ssl.SSLConnectionSocketFactory。

导入org.apache.http.entity.StringEntity。

导入org.apache.http.impl.client.CloseableHttpClient。

导入org.apache.http.impl.client.HttpClients。

导入org.apache.http.impl.conn.PoolingHttpClientConnectionManager。

导入org.apache.http.util.EntityUtils。

导入org.springframework.http.HttpHeaders。

导入javax.imageio.ImageIO;

导入javax.net.ssl.SSLContext;

导入javax.net.ssl.TrustManager;

导入javax.net.ssl.X509TrustManager。

导入java.awt.image.BufferedImage;

导入java.io.ByteArrayInputStream;

导入java.io 文件。

导入java.io.IOException;

导入java.io.InputStream。

导入java.nio.charset.StandardCharsets;

导入java.security.KeyManagementException;

导入java.security.NoSuchAlgorithmException;

导入java.security.SecureRandom;

导入java.security.cert.X509Certificate。

导入java.util.Map。

/**

* 描述:

*

* @作者zjp

* @创建2024/4/26 14:56

*@版本1.0

*/

@slf4j

公共类HttpClientUtils {

/**

* 将不记名令牌身份验证的HTTP 请求发送到指定的URL,绕过HTTPS 证书验证。

*

* @param method HTTP方法(GET、POST、PUT等)

* @param URL 请求URL

* @param requestBodyJson 请求体(JSON格式的字符串,对于非POST/PUT请求可以为空)

* @param header 可选的附加请求头(键值对)

* @return 响应体(JSON格式的字符串),如果请求失败则返回null

* 如果发生网络错误则@抛出IOException

*/

公共静态字符串sendRequest(HttpMethod方法,字符串url,字符串requestBodyJson,MapString,字符串头)抛出IOException,NoSuchAlgorithmException,KeyManagementException {

//创建信任所有证书的SSLContext

SSLContext sslContext=createTrustAllSSLContext();

//创建一个使用此SSLContext的SSLConnectionSocketFactory

SSLConnectionSocketFactory sslSocketFactory=new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

//构建包含SSL 连接工厂的注册表

RegistryConnectionSocketFactorySocketFactoryRegistry=RegistryBuilder.ConnectionSocketFactorycreate().register(\’http\’, PlainConnectionSocketFactory.getSocketFactory()).register(\’https\’, sslSocketFactory).build();

//使用上面的注册表创建一个支持HTTPS的PoolingHttpClientConnectionManager

PoolingHttpClientConnectionManager 连接管理器=new PoolingHttpClientConnectionManager(socketFactoryRegistry);

尝试(CloseableHttpClient httpClient=HttpClients.custom().setConnectionManager(connectionManager).build()) {

HttpUriRequest 请求=createHttpRequest(方法、URL、requestBodyJson、标头);

printHttpRequestDetails(请求);

HttpResponse 响应=httpClient.execute(request);

//打印响应状态行、响应标头和响应正文。

字符串结果=printHttpResponseDetails(响应);

//处理响应

int statusCode=response.getStatusLine().getStatusCode();

if(状态码==200){

返回结果。

} 除此之外{

log.error(\’Error: 请求失败,状态代码\’ + statusCode);

返回空值。

}

} catch(IOException e) {

log.error(\’执行request:时发生异常\’);

e.printStackTrace();

返回空值。

}

}

/**

* 向指定URL发送HTTP请求获取验证码,绕过HTTPS证书验证。

*

* @param method HTTP方法(GET、POST、PUT等)

* @param URL 请求URL

* @param requestBodyJson 请求体(JSON格式的字符串,对于非POST/PUT请求可以为空)

* @param header 可选的附加请求头(键值对)

* @param filePath 图片保存路径

* @return 响应体(JSON格式的字符串),如果请求失败则返回null

* 如果发生网络错误则@抛出IOException

*/

公共静态无效sendImageRequest(HttpMethod方法,字符串url,字符串requestBodyJson,MapString,字符串头,字符串文件路径,字符串文件类型)抛出IOException,NoSuchAlgorithmException,KeyManagementException {

//创建信任所有证书的SSLContext

SSLContext sslContext=createTrustAllSSLContext();

//创建一个使用此SSLContext的SSLConnectionSocketFactory

SSLConnectionSocketFactory sslSocketFactory=new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

//构建包含SSL 连接工厂的注册表

RegistryConnectionSocketFactorySocketFactoryRegistry=RegistryBuilder.ConnectionSocketFactorycreate().register(\’http\’, PlainConnectionSocketFactory.getSocketFactory()).register(\’https\’, sslSocketFactory).build();

//使用上面的注册表创建一个支持HTTPS的PoolingHttpClientConnectionManager

PoolingHttpClientConnectionManager 连接管理器=new PoolingHttpClientConnectionManager(socketFactoryRegistry);

尝试(CloseableHttpClient httpClient=HttpClients.custom().setConnectionManager(connectionManager).build()) {

HttpUriRequest 请求=createHttpRequest(方法、URL、requestBodyJson、标头);

printHttpRequestDetails(请求);

HttpResponse 响应=httpClient.execute(request);

//打印响应状态行、响应标头和响应正文。

downloadImages(响应、文件路径、文件类型);

//处理响应

int statusCode=response.getStatusLine().getStatusCode();

if(状态码==200){

log.info(\’图片下载成功,下载地址为:{}\’, filePath);

} 除此之外{

log.error(\’Error: 请求失败,状态代码\’ + statusCode);

}

} catch(IOException e) {

log.error(\’执行request:时发生异常\’);

e.printStackTrace();

}

}

/**

* 输出HTTP请求详细信息。

*

* @param request HTTP请求对象

*/

私有静态无效printHttpRequestDetails(HttpUriRequest 请求){

log.info(\’\\n—————————————- – — – —- 请求详细信息————————————– — — — ———-\’);

//打印请求方法

log.info(\’Method:\’ + request.getMethod());

//打印请求URI

log.info(\’URI:\’ + request.getURI());

//打印请求头

log.info(\’Headers:\’);

HeaderIterator headerIterator=request.headerIterator();

while (headerIterator.hasNext()) {

标头header=headerIterator.nextHeader();

log.info(header.getName() + \’:\’ + header.getValue());

}

//对于POST或PUT请求,输出请求体

if (关闭RequestBase 的HttpEntityEn 的请求实例) {

HttpEntity 实体=((HttpEntityEnendingRequestBase) 请求).getEntity();

if (实体!=null) {

尝试{

String requestBody=EntityUtils.toString(entity, StandardCharsets.UTF_8);

log.info(\’请求正文:\’ + requestBody);

} catch(IOException e) {

log.error(\’无法打印请求正文:\’);

e.printStackTrace();

}

} 除此之外{

log.info(\’请求体:(空)\’);

}

}

log.info(\’\\n—————————————- – — – ————————————– —– — — ————\\n\’);

}

/**

* 打印HTTP响应详细信息

*

* @返回

*/

私有静态字符串printHttpResponseDetails(HttpResponse 响应) {

log.info(\’\\n—————————————- – —答案详情————————————– —– — — —–\’);

//打印状态行

log.info(\’状态行:\’ + response.getStatusLine());

//打印响应头

System.out.println(\’Headers:\’);

HeaderIterator headerIterator=response.headerIterator();

while (headerIterator.hasNext()) {

标头header=headerIterator.nextHeader();

log.info(header.getName() + \’:\’ + header.getValue());

}

//输出响应体

HttpEntity实体=response.getEntity();

if (实体!=null) {

尝试{

字符串responseBody=EntityUtils.toString(entity, \’UTF-8\’);

log.info(\’响应正文:\’ + 响应正文);

log.info(\’\\n—————————————- – — ———————————————————- – – — —————-\\n\’);

返回响应正文。

} catch(IOException e) {

log.error(\’无法打印响应正文:\’);

log.info(\’\\n—————————————- – — ———————————————————- – – — —————-\\n\’);

e.printStackTrace();

}

} 除此之外{

log.info(\’响应正文:(空)\’);

}

返回空值。

}

/**

* 下载照片

*

* @param 响应HttpResponse

* @param filePath 下载文件的路径

* @param fileType 文件类型(例如png)

*/

私有静态无效downloadImages(HttpResponse响应,字符串文件路径,字符串文件类型){

log.info(\’\\n—————————————- – —答案详情————————————– —– — — —–\’);

//打印状态行

log.info(\’状态行:\’ + response.getStatusLine());

//打印响应头

System.out.println(\’Headers:\’);

HeaderIterator headerIterator=response.headerIterator();

while (headerIterator.hasNext()) {

标头header=headerIterator.nextHeader();

log.info(header.getName() + \’:\’ + header.getValue());

}

//输出响应体

HttpEntity实体=response.getEntity();

if (实体!=null) {

尝试{

//获取响应实体的内容

byte[] imageBytes=EntityUtils.toByteArray(response.getEntity());

//创建输入流

输入流inputStream=new ByteArrayInputStream(imageBytes);

//将字节数组转换为BufferedImage

BufferedImage Image=ImageIO.read(inputStream);

文件输出文件=新文件(文件路径);

//如果父路径不存在则创建

if (!outputFile.getParentFile().exists()) {

OutputFile.getParentFile().mkdirs();

}

ImageIO.write(图像、文件类型、输出文件);

log.info(\’图片下载成功\’);

log.info(\’\\n—————————————- – — ———————————————————- – – — —————-\\n\’);

} catch(IOException e) {

log.error(\’图片下载失败\’);

log.info(\’\\n—————————————- – — ———————————————————- – – — —————-\\n\’);

e.printStackTrace();

}

} 除此之外{

log.info(\’响应正文:(空)\’);

}

}

/**

* 创建HTTP请求对象

*/

私有静态HttpUriRequest createHttpRequest(HttpMethod 方法,字符串URL,字符串requestBodyJson,MapString,字符串标头) 抛出IOException {

HttpUriRequest 请求。

开关(方法){

案例GET:

请求=新的HttpGet(url);

休息;

案例POST:

请求=新的HttpPost(url);

((HttpEntityEn 关闭RequestBase) request).setEntity(new StringEntity(requestBodyJson, \’UTF-8\’));

休息;

案例PUT:

请求=新的HttpPut(url);

((HttpEntityEn 关闭RequestBase) request).setEntity(new StringEntity(requestBodyJson, \’UTF-8\’));

休息;

案例DELETE:

请求=新的HttpDelete(url);

休息;

默认:

throw new IllegalArgumentException(\’不支持的HTTP 方法: \’ + 方法);

}

//设置默认请求头

request.setHeader(HttpHeaders.ACCEPT, \’application/json\’);

request.setHeader(HttpHeaders.CONTENT_TYPE, \’application/json\’);

//添加额外的请求头(如果有)

如果(标题!=空){

for (Map.EntryString, 字符串条目: headers.entrySet()) {

request.setHeader(entry.getKey(),entry.getValue());

}

}

退货请求;

}

/**

* 创建一个信任所有证书的SSLContext

*/

私有静态SSLContext createTrustAllSSLContext() 抛出NoSuchAlgorithmException、KeyManagementException {

SSLContext sslContext=SSLContext.getInstance(\’TLS\’);

sslContext.init(null, new TrustManager[]{new X509TrustManager() {

@覆盖

公共无效checkClientTrusted(X509Certificate [] x509Certificates,字符串s){

}

@覆盖

公共无效checkServerTrusted(X509Certificate [] x509Certificates,字符串s){

}

@覆盖

公共X509Certificate[] getAcceptedIssuers() {

返回新的X509Certificate[0]。

}

}},新的SecureRandom());

返回sslContext。

}

/**

* HTTP方法枚举

*/

公共枚举HttpMethod {

获取、发布、插入、删除

}

}

3.核心功能

3.1安全连接管理

信任所有证书:自定义SSLContext以信任所有SSL证书,避免因证书问题导致请求失败。这特别适合内部测试环境。管理连接池:使用PoolingHttpClientConnectionManager重用连接,提高性能,减少资源消耗。

3.2发送HTTP请求

灵活的HTTP方法支持:支持四种基本的HTTP方法:GET、POST、PUT和DELETE。处理JSON请求体:自动处理JSON格式的请求体,以满足RESTful API的常见需求。 自定义请求头:允许用户添加额外的HTTP头信息,以满足特定的API调用要求。处理响应内容:除了获取JSON格式的响应体外,还可以将图片资源下载到指定路径。

3.3 日志记录

详细的请求/响应日志记录:通过printHttpRequestDetails 和printHttpResponseDetails 方法全面记录请求和响应详细信息,以便于调试和监控。

3.4 异常处理

优雅的错误处理:捕获并记录请求执行过程中可能发生的异常,以确保程序的健壮性。

4.使用示例

4.1发送普通JSON请求

字符串URL=\’https://api.example.com/data\’;

String jsonBody=\'{\\\’键\\\’:\\\’值\\\’}\’;

MapString, 字符串头=new HashMap();

headers.put(\’授权\’, \’承载your_token_here\’);

尝试{

字符串响应=HttpClientUtils.sendRequest(HttpClientUtils.HttpMethod.GET, url, jsonBody, headers);

System.out.println(响应);

} catch (异常e) {

e.printStackTrace();

}

4.2下载图片

字符串imageUrl=\’https://example.com/image.png\’;

String savePath=\’/path/to/save/image.png\’;

尝试{

HttpClientUtils.sendImageRequest(HttpClientUtils.HttpMethod.GET, imageUrl, \’\’, null, savePath,\’png\’);

} catch (异常e) {

e.printStackTrace();

}

5. 拓展HTTP方法(HTTP Methods)

1.在HttpMethod枚举类中添加了新的HTTP方法(HTTP method)。

2. createHttpRequest方法中添加了一个新的case方法。

6.总结

HttpClientUtils工具类集成了Apache HttpClient的强大功能,结合了简化的证书验证、请求响应日志记录和灵活的HTTP方法支持等功能,可以提高开发人员在进行HTTP通信时的效率,并极大地改善您的体验。无论是日常的API调用,还是复杂的数据交互场景,该工具类都能提供稳定可靠的解决方案。在实际应用中,根据您的具体需求,您可以通过添加请求重试机制、超时设置等进一步扩展功能,以适应更多样化的应用场景。

以上关于#HttpClient工具类的相关内容摘自互联网,仅供参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91646.html

(0)
CSDN's avatarCSDN
上一篇 2024年6月22日 下午11:31
下一篇 2024年6月22日 下午11:49

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注