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