HttpUtils工具类 httpclient5+okhttp
HttpUtils工具类(一)常见的HttpUtils工具类及如何自定义java的http连接池-CSDN博客
一、几种常见的Http调用方式
- Apache HttpClient
- OKhttpClient
- Hutool封装的HttpUtils
- Spring RestTemplate
- Java 原生的HttpURLConnection
1. 使用 Apache HttpClient
Apache HttpClient 是一个功能强大的 HTTP 客户端库,支持同步和异步请求。它适用于处理更加复杂的场景,如认证、连接池、多线程、上传文件等。
特点:
- 功能强大:Apache HttpClient 是一个久经考验的库,支持多种复杂的场景,包括连接池、代理、认证、重定向、Cookie 管理等。
- 扩展性好:可以通过丰富的 API 进行灵活配置,满足复杂的企业级应用需求。
- 同步阻塞:Apache HttpClient 默认是同步阻塞模式,适用于同步请求。
优点:
- 成熟稳定,经过长时间的验证,企业级项目中广泛使用。
- 适合需要复杂 HTTP 操作的场景,如带有重试、认证和状态维护的请求。
缺点:
- 比较重量级,学习曲线稍陡峭。
maven依赖:
-
<dependency>
-
<groupId>org.apache.httpcomponents</groupId>
-
<artifactId>httpclient</artifactId>
-
<version>4.5.13</version>
-
</dependency>
2. 使用 OKhttpClient
官网(概述 - OkHttp (square.github.io))
OKhttpClient是一个轻量级且性能出色的 HTTP 客户端,支持同步和异步请求,广泛应用于 Android 开发中。
特点:
- 轻量级且高效:OkHttpClient 是由 Square 开发的轻量级 HTTP 客户端库,广泛用于 Android 开发中。
- 同步与异步请求:支持同步阻塞和异步非阻塞请求,异步操作非常简单且性能良好。
- 连接复用:内置连接池,减少重复连接带来的开销,尤其适合在 Android 和 Web 应用中使用。
优点:
- 性能优异,尤其适合移动端和需要高并发的场景。
- API 简单易用,支持异步调用,非常适合需要频繁发起网络请求的应用场景。
缺点:
- 功能相对较少,某些复杂功能需要自定义扩展。
maven依赖:
-
<dependency>
-
<groupId>com.squareup.okhttp3</groupId>
-
<artifactId>okhttp</artifactId>
-
<version>4.9.0</version>
-
</dependency>
3. 使用第三方库(Hutool)的http链接池
官网(Http客户端工具类-HttpUtil (hutool.cn))
Hutool-http针对JDK的HttpUrlConnection做一层封装,简化了HTTPS请求、文件上传、Cookie记忆等操作,使Http请求变得无比简单。
Hutool-http的核心集中在两个类:
- HttpRequest
- HttpResponse
同时针对大部分情境,封装了HttpUtil工具类。
优点:
- 根据URL自动判断是请求HTTP还是HTTPS,不需要单独写多余的代码。
- 表单数据中有File对象时自动转为
multipart/form-data表单,不必单做做操作。 - 默认情况下Cookie自动记录,比如可以实现模拟登录,即第一次访问登录URL后后续请求就是登录状态。
- 自动识别304跳转并二次请求
- 自动识别页面编码,即根据header信息或者页面中的相关标签信息自动识别编码,最大可能避免乱码。
- 自动识别并解压Gzip格式返回内容
特点:
- 工具化封装:Hutool 是一个 Java 工具库,其封装的
HttpUtils提供了简洁的 API,用于发送 HTTP 请求。与 Apache HttpClient 和 OkHttp 相比,Hutool 封装的HttpUtils更加简化和易用,适合快速开发。 - 轻量级:Hutool 的封装非常轻量,主要面向日常开发中的小型任务。
- 默认处理:支持自动化处理请求头、超时、编码等,开发者只需关注核心业务逻辑。
优点:
- API 简单易用,能快速上手,适合需要快速开发和简洁代码的项目。
- Hutool 提供了丰富的其他工具类,整合使用可以大大提升开发效率。
缺点:
- 不适合处理过于复杂的 HTTP 场景,定制化能力弱于 Apache HttpClient 和 OkHttp。
- 适用于一般场景下的快速开发,复杂场景可能需要自行扩展或使用其他库。
maven依赖:
-
<dependency>
-
<groupId>cn.hutool</groupId>
-
<artifactId>hutool-all</artifactId>
-
<version>5.8.16</version>
-
</dependency>
4. 使用 Spring RestTemplate
RestTemplate 是 Spring 提供的用于调用 RESTful Web 服务的工具类,简化了发送 HTTP 请求和处理响应的操作。
5. 使用 Java 原生的HttpURLConnection
HttpURLConnection 是 Java 自带的用于发送 HTTP 请求的类。它适合处理简单的 GET、POST 请求,但对于更复杂的需求(如多部分表单数据上传、流式处理等),需要自己编写更多的代码
二、总结
- 简单场景:
HttpURLConnection和RestTemplate、Hutools的HttpUtils。 - 复杂场景:
Apache HttpClient和OkHttpClient,用于处理认证、连接池、文件上传等定制化需求。
常用三种HttpUtils对比总结
- Apache HttpClient:适用于复杂的企业级应用,功能齐全,特别是在处理高级 HTTP 功能如认证、代理、连接池等方面表现出色。
- OkHttpClient:轻量级且高效,适合高并发、移动端应用(如 Android 开发)以及需要异步请求的场景,性能好且使用简单。
- Hutool 封装的 HttpUtils:工具类封装简洁,适合快速开发和处理简单的 HTTP 请求,适合轻量级项目。
可以根据项目需求选择合适的工具可以有效简化 HTTP 请求的处理逻辑。
=======================================================
接下来,将围绕
- Apache HttpClient
- OKhttpClient
这两种自定义Http连接池,并列举相应的例子。
HttpUtils工具类(二)Apache HttpClient 5 使用详细教程_apache client5-CSDN博客
一、Apache HttpClient 5介绍
Apache HttpClient 5 是一个功能齐全且高度可定制的 HTTP 客户端库, 其专门用于发送 HTTP 请求、处理 HTTP 响应并支持各种 HTTP 协议特性。特别适合处理复杂的 HTTP 请求需求,如多协议支持、认证、连接池、代理等。它适合中大型项目或需要高级 HTTP 特性的应用开发。
(1)核心特性
-
功能强大:
- 同步与异步支持:支持同步和异步的 HTTP 请求处理,异步请求在处理大量并发请求时能够显著提高效率。
- 连接池管理:内置的连接池机制能提高并发处理性能,减少资源消耗。
- 多种认证机制:支持多种认证方式,包括 Basic、Digest、NTLM、Kerberos 等,能够处理多种安全场景。
- 支持Cookie管理:内置 Cookie 管理功能,能够自动处理服务端返回的 Cookie 并在后续请求中使用,模拟浏览器行为。
-
协议支持广泛:
- HTTP/1.1 和 HTTP/2 支持:支持现代 HTTP 协议,包括 HTTP/2 的多路复用和流优先级等特性,提升了网络请求效率;特别是 HTTP/2 多路复用的优势。
- SSL/TLS 支持:支持 HTTPS,提供自定义 SSL/TLS 配置,确保通信的安全性。HttpClient 5 可以方便地处理 HTTPS 请求,支持定制化的 SSL/TLS 配置。
-
灵活性和可扩展性:
- 易于扩展和定制:允许开发者根据需要进行灵活的定制,HttpClient 5 的设计高度模块化,用户可以根据需要对连接管理、重定向策略、请求重试策略、代理设置等进行灵活定制。
- 代理支持:可以轻松配置 HTTP 或 SOCKS 代理,用于跨网络访问和隐私保护。
-
健壮的错误处理机制:
- 自动重试和重定向处理:内置的重试机制和自动重定向处理,可以减少由于网络问题导致的失败请求。开发者可以定制是否启用自动重定向。
(2)Apache HttpClient 5 的新特性
与之前的 4.x 版本相比,HttpClient 5 进行了大量的改进和优化,特别是在性能和安全性方面:
- HTTP/2 支持:提供了完整的 HTTP/2 支持,包括多路复用、流优先级等特性。
- 更好的异步支持:在处理并发请求时,通过异步模型极大提升了响应速度和吞吐量。
- 灵活的响应处理:通过改进的响应处理 API,可以更方便地处理大型响应体,避免内存溢出问题。
(3)在 Java 项目的主要使用场景及缺点
使用场景:
- RESTful API 客户端:与第三方 API 交互,发送各种 HTTP 请求。
- Web 爬虫:抓取网页内容,处理重定向、Cookie 等。
- 分布式系统通信:用于微服务间的 HTTP 通信。
- 测试与自动化:模拟 HTTP 请求,进行集成和自动化测试。
- 代理与网关:处理请求代理和认证机制。
- 文件上传下载:实现大文件的传输。
- 认证交互:处理 OAuth2、JWT 等认证协议。
- 安全通信:处理 HTTPS 请求,确保数据安全。
缺点:
- 学习曲线陡峭:高级特性(如自定义连接池、SSL 配置、异步请求等)较为复杂,新手需要时间学习和掌握。
- 体积较大:相比轻量级客户端,如 OkHttp,HttpClient 依赖库较多,可能不适合小型项目。
- 性能消耗高:默认配置下的内存和 CPU 占用较高,需调整才能达到最佳性能。
- 配置繁琐:高级定制(如连接管理、认证、代理)需要较多配置,增加开发复杂度。
- 异步编程复杂:异步请求的回调、错误处理等逻辑复杂,增加代码难度。
二、在实际项目中的应用
(1)引入maven配置
首先,你需要将 HttpClient 5 的依赖加入到项目中。pom.xml 文件如下:
-
<dependency>
-
<groupId>org.apache.httpcomponents.client5</groupId>
-
<artifactId>httpclient5</artifactId>
-
<version>5.1</version>
-
</dependency>
(2)自定义HttpUtils工具类---实现连接管理、重试策略等
-
import lombok.extern.slf4j.Slf4j;
-
import org.apache.hc.client5.http.DnsResolver;
-
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.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.client5.http.impl.io.PoolingHttpClientConnectionManager;
-
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
-
import org.apache.hc.core5.http.HttpEntity;
-
import org.apache.hc.core5.http.io.SocketConfig;
-
import org.apache.hc.core5.http.message.BasicHeader;
-
import org.apache.hc.core5.util.Timeout;
-
import org.springframework.stereotype.Component;
-
-
import java.io.Closeable;
-
import java.io.IOException;
-
import java.net.InetAddress;
-
import java.net.URI;
-
import java.net.UnknownHostException;
-
import java.util.Map;
-
-
-
/**
-
* @author 响叮当
-
* @since 2024/8/15 14:10
-
**/
-
-
-
public class ApacheHttpClientUtil {
-
-
private CloseableHttpClient httpClient;
-
-
-
public void init() {
-
SocketConfig socketConfig = SocketConfig.custom()
-
.setSoTimeout(Timeout.ofMilliseconds(1000))
-
.build();
-
-
PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder
-
.create()
-
.setDefaultSocketConfig(socketConfig)
-
.setMaxConnTotal(1000)
-
.setMaxConnPerRoute(50)
-
.build();
-
-
RequestConfig requestConfig = RequestConfig.custom()
-
.setConnectionRequestTimeout(Timeout.ofMilliseconds(8000))
-
.setResponseTimeout(Timeout.ofMilliseconds(8000))
-
.setConnectTimeout(Timeout.ofMilliseconds(8000))
-
.build();
-
-
httpClient = HttpClients
-
.custom()
-
.disableContentCompression()
-
.setConnectionManager(connectionManager)
-
.setDefaultRequestConfig(requestConfig)
-
.build();
-
}
-
-
-
public CloseableHttpResponse getOrHead(String url, String method, Map<String, String> headers) throws IOException {
-
HttpUriRequestBase request = new HttpUriRequestBase(method, URI.create(url));
-
BasicHeader[] head = mapToHeaders(headers);
-
request.setHeaders(head);
-
return httpClient.execute(request);
-
}
-
-
-
public CloseableHttpResponse post(String url, Map<String, String> headers, HttpEntity httpEntity) throws IOException {
-
HttpPost request = new HttpPost(url);
-
BasicHeader[] head = mapToHeaders(headers);
-
request.setHeaders(head);
-
request.setEntity(httpEntity);
-
return httpClient.execute(request);
-
}
-
-
public static BasicHeader[] mapToHeaders(Map<String, String> map) {
-
BasicHeader[] headers = new BasicHeader[map.size()];
-
int i = 0;
-
for (Map.Entry<String, String> entry : map.entrySet()) {
-
headers[i++] = new BasicHeader(entry.getKey(), entry.getValue());
-
}
-
return headers;
-
}
-
-
public static void closeQuietly(Closeable is) {
-
if (is != null) {
-
try {
-
is.close();
-
} catch (Exception ex) {
-
log.error("Resources encounter an exception when closing,ex:{}", ex.getMessage());
-
}
-
}
-
}
-
-
}
功能概述
- 初始化 HTTP 客户端:
init()方法初始化CloseableHttpClient,配置连接池、请求超时和套接字超时。- 连接池配置:通过
PoolingHttpClientConnectionManagerBuilder设置最大连接数(1000)和每路由的最大连接数(50),用于高并发场景。 - 请求配置:包括连接超时、请求超时和响应超时,确保在合理的时间内处理请求。
- 连接池配置:通过
- HTTP 请求处理:
- GET/HEAD 请求:
getOrHead()方法可发送 GET 或 HEAD 请求,并接受自定义请求头。 - POST 请求:
post()方法可发送 POST 请求,支持自定义请求头和实体。
- GET/HEAD 请求:
- 资源管理:
closeQuietly()方法用于关闭资源,避免抛出异常。
(3)代码中的具体实现
1、Get请求
-
-
public void testGet() {
-
String url = "http://xxx.com.cn";
-
try {
-
// 1、构建入参、添加 headers
-
Map<String, String> headers = new HashMap<>();
-
-
// 2、发起http请求
-
CloseableHttpResponse httpResponse = apacheHttpClientUtil.getOrHead(url, "GET", headers);
-
-
// 3、返回结果,异常处理
-
if (httpResponse.getCode() == 200) {
-
String resStr = EntityUtils.toString(httpResponse.getEntity());
-
log.info("request_success, response:{}, httpResponse_Code:{}, reasonPhrase:{}", resStr, httpResponse.getCode(), httpResponse.getReasonPhrase());
-
} else {
-
log.error("request_fail, httpResponse_Code:{}, reasonPhrase:{}", httpResponse.getCode(), httpResponse.getReasonPhrase());
-
}
-
} catch (Exception e) {
-
log.error("request_udmp_fail, ex:{}", e);
-
}
-
}
2、POST请求-常规
-
-
public void testPost( PostReq req) {
-
String url = "http://xxx.com.cn";
-
try {
-
// 1、构建入参、添加 headers
-
StringEntity stringEntity = new StringEntity(JSONUtil.toJsonStr(req), ContentType.APPLICATION_JSON);
-
Map<String, String> headers = new HashMap<>();
-
-
// 2、发起http请求
-
CloseableHttpResponse httpResponse = apacheHttpClientUtil.post(url, headers, stringEntity);
-
-
// 3、返回结果,异常处理
-
if (httpResponse.getCode() == 200) {
-
String resStr = EntityUtils.toString(httpResponse.getEntity());
-
log.info("request_success, response:{}, httpResponse_Code:{}, reasonPhrase:{}", resStr, httpResponse.getCode(), httpResponse.getReasonPhrase());
-
} else {
-
log.error("request_fail, httpResponse_Code:{}, reasonPhrase:{}", httpResponse.getCode(), httpResponse.getReasonPhrase());
-
}
-
} catch (Exception e) {
-
log.error("request_udmp_fail, ex:{}", e);
-
}
-
}
3、POST请求-上传文件
-
/**
-
* 上传文件
-
* @param multipartFile
-
* @param token
-
* @param key
-
* @return
-
*/
-
-
public UploadRes testPostFile(
-
MultipartFile multipartFile,
-
String token,
-
String key
-
) {
-
UploadRes res = null;
-
String url = "http://xxx.com.cn";
-
try {
-
// 1、构建File参数
-
File file = new File(multipartFile.getOriginalFilename());
-
try (FileOutputStream fos = new FileOutputStream(file)) {
-
fos.write(multipartFile.getBytes());
-
}
-
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
-
builder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, "ex.xlsx");
-
-
// 2、构建其他参数
-
builder.addTextBody("token", token, ContentType.TEXT_PLAIN);
-
builder.addTextBody("key", key, ContentType.TEXT_PLAIN);
-
HttpEntity multipartEntity = builder.build();
-
-
// 3、需要加 header,在这里加
-
Map<String, String> headers = new HashMap<>();
-
-
// 4、发起http请求
-
CloseableHttpResponse httpResponse = apacheHttpClientUtil.post(url, headers, multipartEntity);
-
-
// 5、返回结果,异常处理
-
if (httpResponse.getCode() == 200) {
-
String resStr = EntityUtils.toString(httpResponse.getEntity());
-
res = JSONUtil.toBean(resStr, UploadRes.class);
-
log.info("request_success, response:{}, httpResponse_Code:{}, reasonPhrase:{}", resStr, httpResponse.getCode(), httpResponse.getReasonPhrase());
-
} else {
-
log.error("request_fail, httpResponse_Code:{}, reasonPhrase:{}", httpResponse.getCode(), httpResponse.getReasonPhrase());
-
}
-
} catch (Exception e) {
-
log.error("request_udmp_fail, ex:{}", e);
-
}
-
return res;
-
}
(4)高级用法
1、处理重定向
HttpClient 5 默认会处理 3XX 重定向,但你也可以自定义行为。
-
CloseableHttpClient httpClient = HttpClients.custom()
-
.disableRedirectHandling() // 禁用自动重定向
-
.build();
2、SSL/TLS 支持
使用 HttpClient 5 可以轻松处理 HTTPS 请求,下面展示如何自定义 SSL 配置。
-
import org.apache.hc.core5.ssl.SSLContextBuilder;
-
import org.apache.hc.client5.http.impl.classic.HttpClients;
-
import javax.net.ssl.SSLContext;
-
-
SSLContext sslContext = SSLContextBuilder.create()
-
.loadTrustMaterial((chain, authType) -> true) // 信任所有证书
-
.build();
-
-
CloseableHttpClient httpClient = HttpClients.custom()
-
.setSSLContext(sslContext)
-
.build();
3、处理异步请求
如果你需要发送异步 HTTP 请求,可以使用 HttpAsyncClient。
-
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
-
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
-
import org.apache.hc.core5.concurrent.FutureCallback;
-
import org.apache.hc.client5.http.classic.methods.HttpGet;
-
-
CloseableHttpAsyncClient asyncClient = HttpAsyncClients.createDefault();
-
-
asyncClient.start();
-
-
HttpGet request = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");
-
-
asyncClient.execute(request, new FutureCallback<>() {
-
-
public void completed(CloseableHttpResponse response) {
-
System.out.println("Response received: " + response.getCode());
-
}
-
-
-
public void failed(Exception ex) {
-
System.out.println("Request failed: " + ex.getMessage());
-
}
-
-
-
public void cancelled() {
-
System.out.println("Request cancelled");
-
}
-
});
4、处理 Cookie
-
import org.apache.hc.client5.http.cookie.BasicCookieStore;
-
import org.apache.hc.client5.http.impl.classic.HttpClients;
-
import org.apache.hc.client5.http.cookie.CookieStore;
-
-
CookieStore cookieStore = new BasicCookieStore();
-
CloseableHttpClient httpClient = HttpClients.custom()
-
.setDefaultCookieStore(cookieStore)
-
.build();
5、HTTPDNS支持
-
// 当域名为www.baidu.com结尾时候,转到local的机器上
-
String Target_IP= "127.0.0.1";
-
String[] domains = new String[]{"www.baidu.com"};
-
-
DnsResolver dnsResolver = new DnsResolver() {
-
-
public InetAddress[] resolve(String host) throws UnknownHostException {
-
if (host.endsWith(domains[0]))) {
-
return new InetAddress[]{InetAddress.getByName(Target_IP)};
-
}
-
return new InetAddress[0];
-
}
-
-
-
public String resolveCanonicalHostname(String s) {
-
return null;
-
}
-
};
-
-
-
// @PostConstruct
-
public void init() {
-
SocketConfig socketConfig = SocketConfig.custom()
-
.setSoTimeout(Timeout.ofMilliseconds(1000))
-
.build();
-
-
PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder
-
.create()
-
.setDnsResolver(dnsResolver) // 这里是HttpDns配置
-
.setDefaultSocketConfig(socketConfig)
-
.setMaxConnTotal(1000)
-
.setMaxConnPerRoute(50)
-
.build();
HttpUtils工具类(三)OKHttpClient使用详细教程-CSDN博客
OkHttpClient 是一个由 Square 公司开发的 HTTP 客户端库,用于在 Android 和 Java 应用中进行网络请求。它支持同步和异步请求、连接池、超时设置、拦截器等功能,适合用于高性能网络请求,特别是在需要处理复杂的网络操作时。
一、OKHttpClient介绍
主要特点
-
同步和异步请求:
-
同步请求会在当前线程等待响应,适合不需要并发的简单请求。
-
异步请求会将网络操作交由后台线程处理,不会阻塞主线程,适合需要并发处理或在 Android 等环境中使用。
-
-
连接池: OkHttp 默认会使用连接池来复用 HTTP 连接,从而提高性能,减少连接的建立和关闭的开销。
-
拦截器 (Interceptor): 拦截器允许在请求和响应时进行操作,例如可以在请求发送前添加认证信息,或在响应到达后进行日志记录。
-
自动处理 HTTP/2 和 SPDY: OkHttp 默认支持 HTTP/2 协议,可以提升多路复用性能,使多个请求共享一个 TCP 连接。
-
缓存机制: OkHttp 提供了默认的缓存机制,可以根据 HTTP 响应头自动缓存请求结果,减少重复网络请求。
-
超时控制: 可以对连接、读取和写入操作分别设置超时,避免长时间无响应的请求卡住应用。
二、在实际项目中的应用
(1)引入maven配置
-
<!-- ok的Http连接池 -->
-
<dependency>
-
<groupId>com.squareup.okhttp3</groupId>
-
<artifactId>okhttp</artifactId>
-
<version>4.9.3</version>
-
</dependency>
(2)自定义HttpUtils工具类
-
import com.alibaba.fastjson.JSONObject;
-
import com.yan.project.httpUtils.okHttp2.HttpRequestBody;
-
import lombok.extern.slf4j.Slf4j;
-
import okhttp3.*;
-
-
import java.io.Closeable;
-
import java.io.File;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.util.Map;
-
import java.util.Objects;
-
import java.util.Set;
-
import java.util.concurrent.TimeUnit;
-
-
@Slf4j
-
public class OkHttpUtils {
-
private OkHttpUtils() {
-
throw new IllegalArgumentException("Utility class");
-
}
-
-
private static final String MIME_JSON = "application/json; charset=utf-8";
-
-
private static OkHttpClient httpClient = new OkHttpClient.Builder()
-
.connectTimeout(3, TimeUnit.SECONDS)
-
.writeTimeout(5, TimeUnit.SECONDS)
-
.readTimeout(5, TimeUnit.SECONDS)
-
.addInterceptor((Interceptor.Chain chain) -> {
-
Request req = chain.request();
-
try {
-
Response res = chain.proceed(req);
-
return res;
-
} catch (Exception ex) {
-
throw ex;
-
}
-
})
-
.build();
-
-
// GET-无参
-
public static String getJson(String url) throws IOException {
-
return basicGet(url, null);
-
}
-
-
// GET-有参
-
public static String get(String url, Map<String, Object> paramMap) throws Exception {
-
StringBuilder sb = new StringBuilder(url);
-
if (paramMap != null && !paramMap.isEmpty()) {
-
Set<String> keySet = paramMap.keySet();
-
for (String key : keySet) {
-
sb.append(sb.toString().contains("?") ? "&" : "?");
-
sb.append(key).append("=").append(paramMap.get(key));
-
}
-
url = sb.toString();
-
}
-
return basicGet(url, null);
-
}
-
-
-
// GET-有参、有请求头
-
public static String getWithHeades(String url, Map<String, Object> paramMap, Map<String, String> headers) throws Exception {
-
StringBuilder sb = new StringBuilder(url);
-
if (paramMap != null && !paramMap.isEmpty()) {
-
Set<String> keySet = paramMap.keySet();
-
for (String key : keySet) {
-
sb.append(sb.toString().contains("?") ? "&" : "?");
-
sb.append(key).append("=").append(paramMap.get(key));
-
}
-
url = sb.toString();
-
}
-
return basicGet(url, headers);
-
}
-
-
// GET-json
-
public static String getJsonWithHeader(String url, Map<String, String> headerMap) throws IOException {
-
Request.Builder request = new Request.Builder().url(url).get().header("Accept", MIME_JSON);
-
if (headerMap != null) {
-
headerMap.forEach(request::header);
-
}
-
try (Response response = httpClient.newCall(request.build()).execute()) {
-
log.info("response_code:{}, response_body:{}", response.code(), response.body().string());
-
return response.body().string();
-
}
-
}
-
-
-
// POST-json传参
-
public static String postJsonWithHeader(String url, Object reqBody, Map<String, String> headers) throws IOException {
-
Request.Builder request = new Request.Builder()
-
.url(url)
-
.header("Accept", MIME_JSON)
-
.post(FormBody.create(MediaType.parse(MIME_JSON), JSONObject.toJSONString(reqBody)));
-
// 遍历并添加 header
-
if (headers != null) {
-
headers.forEach(request::header);
-
}
-
-
try (Response response = httpClient.newCall(request.build()).execute()) {
-
log.info("response_code:{}, response_body:{}", response.code(), response.body().string());
-
return response.body().string();
-
}
-
}
-
-
// POST-param传参
-
public static String postParamWithHeader(String url, Map<String, Object> paramMap, Map<String, String> headers) throws IOException {
-
FormBody.Builder formBody = new FormBody.Builder();
-
if (Objects.nonNull(paramMap)) {
-
paramMap.forEach((k, v) -> formBody.add(k, (String) v));
-
}
-
-
Request.Builder request = new Request.Builder()
-
.url(url)
-
.header("Accept", MIME_JSON)
-
.post(formBody.build());
-
-
// 遍历并添加 header
-
if (headers != null) {
-
headers.forEach(request::header);
-
}
-
-
try (Response response = httpClient.newCall(request.build()).execute()) {
-
log.info("response_code:{}, response_body:{}", response.code(), response.body().string());
-
return response.body().string();
-
}
-
}
-
-
public static final String octet_stream_str = "application/octet-stream";
-
public static final MediaType octet_stream = MediaType.parse(octet_stream_str);
-
-
public static void putStream(String url, InputStream inputStream, long contentLength) {
-
Response response;
-
try {
-
RequestBody requestBody2 = new HttpRequestBody(inputStream, contentLength);
-
-
Request request = new Request.Builder().url(url)
-
.addHeader("Content-Type", octet_stream_str)
-
.put(requestBody2)
-
.build();
-
response = httpClient.newCall(request).execute();
-
-
String result = response.body().string();
-
if (response.code() != 200) {
-
throw new Exception("Saturn SDK stream upload failed, url:" + url + "response.code():" + response.code() + ", msg:" + result);
-
}
-
} catch (Exception e) {
-
e.printStackTrace();
-
} finally {
-
closeQuietly(inputStream);
-
}
-
}
-
-
-
public static String putFile(String url, File file) throws Exception {
-
RequestBody requestBody = RequestBody.create(octet_stream, file);
-
Request request = new Request.Builder().url(url)
-
.addHeader("Content-Type", octet_stream_str)
-
.put(requestBody).build();
-
-
Response response = httpClient.newCall(request).execute();
-
String result = response.body().string();
-
int code = response.code();
-
log.info("putFile end, url:{}, response.code:{}, result:{}", url, code, result);
-
if (code != 200) {
-
throw new Exception("putFile failed, response.code():" + code + ", result:" + result);
-
}
-
return result;
-
}
-
-
-
private static String basicGet(String url, Map<String, String> headers) throws IOException {
-
Request.Builder builder = new Request.Builder()
-
.url(url)
-
.get();
-
// 遍历并添加 header
-
if (headers != null) {
-
headers.forEach(builder::header);
-
}
-
-
try (Response response = httpClient.newCall(builder.build()).execute()) {
-
return response.body().string();
-
}
-
}
-
-
private static String basicDelete(String url, Headers headers) throws IOException {
-
Request.Builder builder = new Request.Builder().url(url).delete();
-
if (headers != null) {
-
builder.headers(headers);
-
}
-
try (Response response = httpClient.newCall(builder.build()).execute()) {
-
return response.body().string();
-
}
-
}
-
-
public static void closeQuietly(Closeable is) {
-
if (is != null) {
-
try {
-
is.close();
-
} catch (Exception ex) {
-
log.error("Resources encounter an exception when closing,ex:{}", ex.getMessage());
-
}
-
}
-
}
-
}
这个
OkHttpUtils类封装了OkHttpClient来进行 HTTP 请求,支持 GET、POST、PUT 等常见的 HTTP 方法,并提供了对参数、请求头、文件上传等功能的支持。以下是它的主要功能和使用方法的解释:
OkHttpClient 实例
使用
OkHttpClient.Builder()创建,设置了超时时间(连接超时 3 秒,读写超时 5 秒),并添加了拦截器。静态方法
getJson,get,getWithHeades,getJsonWithHeader:用于 GET 请求,支持无参、有参数和请求头的场景。
postJsonWithHeader,postParamWithHeader:用于 POST 请求,支持 JSON 数据或表单数据传递。
putStream,putFile:用于 PUT 请求,支持流和文件上传。
basicGet,basicDelete:内部通用方法,分别处理 GET 和 DELETE 请求。
三、拓展和使用建议
- 增强错误处理:当前仅在拦截器中简单处理了异常,可以考虑在各个方法中增加详细的异常处理机制。
- 连接池管理:默认情况下,OkHttp 使用连接池来提升性能,类内部也可以进一步定制连接池策略来优化并发性能。
- 异步支持:所有请求均为同步请求,适合使用时可以考虑用 OkHttp 提供的
enqueue()方法进行异步操作,防止阻塞主线程。
通过这些封装,OkHttpUtils 能够方便地发送 HTTP 请求并处理响应。在实际项目中,你可以根据需要调整超时设置、缓存机制等配置。

浙公网安备 33010602011771号