当前位置: 首页 > news >正文

HttpUtils工具类(三)OKHttpClient使用详细教程

OkHttpClient 是一个由 Square 公司开发的 HTTP 客户端库,用于在 Android 和 Java 应用中进行网络请求。它支持同步和异步请求、连接池、超时设置、拦截器等功能,适合用于高性能网络请求,特别是在需要处理复杂的网络操作时。

一、OKHttpClient介绍

主要特点

  1. 同步和异步请求

    • 同步请求会在当前线程等待响应,适合不需要并发的简单请求。

    • 异步请求会将网络操作交由后台线程处理,不会阻塞主线程,适合需要并发处理或在 Android 等环境中使用。

  2. 连接池: OkHttp 默认会使用连接池来复用 HTTP 连接,从而提高性能,减少连接的建立和关闭的开销。

  3. 拦截器 (Interceptor): 拦截器允许在请求和响应时进行操作,例如可以在请求发送前添加认证信息,或在响应到达后进行日志记录。

  4. 自动处理 HTTP/2 和 SPDY: OkHttp 默认支持 HTTP/2 协议,可以提升多路复用性能,使多个请求共享一个 TCP 连接。

  5. 缓存机制: OkHttp 提供了默认的缓存机制,可以根据 HTTP 响应头自动缓存请求结果,减少重复网络请求。

  6. 超时控制: 可以对连接、读取和写入操作分别设置超时,避免长时间无响应的请求卡住应用。

二、在实际项目中的应用

(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-jsonpublic 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)));// 遍历并添加 headerif (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());// 遍历并添加 headerif (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();// 遍历并添加 headerif (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 方法,并提供了对参数、请求头、文件上传等功能的支持。以下是它的主要功能和使用方法的解释:

  1. OkHttpClient 实例

    • 使用 OkHttpClient.Builder() 创建,设置了超时时间(连接超时 3 秒,读写超时 5 秒),并添加了拦截器。

  2. 静态方法

    • getJson, get, getWithHeades, getJsonWithHeader:用于 GET 请求,支持无参、有参数和请求头的场景。

    • postJsonWithHeader, postParamWithHeader:用于 POST 请求,支持 JSON 数据或表单数据传递。

    • putStream, putFile:用于 PUT 请求,支持流和文件上传。

    • basicGet, basicDelete:内部通用方法,分别处理 GET 和 DELETE 请求。

三、拓展和使用建议

  • 增强错误处理:当前仅在拦截器中简单处理了异常,可以考虑在各个方法中增加详细的异常处理机制。
  • 连接池管理:默认情况下,OkHttp 使用连接池来提升性能,类内部也可以进一步定制连接池策略来优化并发性能。
  • 异步支持:所有请求均为同步请求,适合使用时可以考虑用 OkHttp 提供的 enqueue() 方法进行异步操作,防止阻塞主线程。

通过这些封装,OkHttpUtils 能够方便地发送 HTTP 请求并处理响应。在实际项目中,你可以根据需要调整超时设置、缓存机制等配置。

相关文章:

HttpUtils工具类(三)OKHttpClient使用详细教程

OkHttpClient 是一个由 Square 公司开发的 HTTP 客户端库&#xff0c;用于在 Android 和 Java 应用中进行网络请求。它支持同步和异步请求、连接池、超时设置、拦截器等功能&#xff0c;适合用于高性能网络请求&#xff0c;特别是在需要处理复杂的网络操作时。 一、OKHttpClien…...

重生奇迹MU老大哥剑士职业宝刀未老

重生奇迹MU中&#xff0c;老大哥剑士职业一直以来备受玩家们的喜爱。这个职业不仅拥有强大的攻击力、防御力和战斗技巧&#xff0c;而且还能够通过使用各种宝刀来增强自身的战斗能力。即便经过了多年的沉淀&#xff0c;老大哥剑士依然是一名宝刀未老的男人&#xff0c;仍然能够…...

关于Netty详细介绍,Netty原理架构解析

Netty 是什么 1&#xff09;Netty 是 JBoss 开源项目&#xff0c;是异步的、基于事件驱动的网络应用框架&#xff0c;它以高性能、高并发著称。所谓基于事件驱动&#xff0c;说得简单点就是 Netty 会根据客户端事件&#xff08;连接、读、写等&#xff09;做出响应&#xff0c;…...

在Unity环境中使用UTF-8编码

为什么要讨论这个问题 为了避免乱码和更好的跨平台 我刚开始开发时是使用VS开发,Unity自身默认使用UTF-8 without BOM格式,但是在Unity中创建一个脚本,使用VS打开,VS自身默认使用GB2312(它应该是对应了你电脑的window版本默认选取了国标编码,或者是因为一些其他的原因)读取脚本…...

零工市场小程序:自由职业者的日常工具

零工市场小程序多功能且便捷&#xff0c;提供了前所未有的灵活性和工作效率。这类小程序不仅改变了自由职业者的工作方式&#xff0c;也重塑了劳动力市场的格局。 一、零工市场小程序的特点 即时匹配&#xff1a;利用先进的数据算法&#xff0c;零工市场小程序能够快速匹配自由…...

【Http 每日一问,访问服务端的鉴权Token放在header还是cookie更合适?】

结论先行&#xff1a; token静态的&#xff0c;不变的&#xff0c;放在header里面。 典型场景 &#xff0c;每次访问时需要带个静态token请求服务端&#xff0c;向服务端表明是谁请求&#xff0c;此时token也可以认为是个固定的access-key。token动态的&#xff0c;会失效&…...

vue2+ueditor集成秀米编辑器

一、百度富文本编辑器 1.首先下载 百度富文本编辑器 下载地址&#xff1a;GitHub - fex-team/ueditor: rich text 富文本编辑器 2.把下载好的文件整理好 放在图片目录下 3. 安装插件vue-ueditor-wrap npm install vue-ueditor-wrap 4.在你所需要展示的页面 引入vue-uedito…...

[网络]HTTP协议 Cookie与Session

一、Cookie 1.1 定义 HTTP Cookie&#xff08;也称为 Web Cookie、浏览器 Cookie 或简称 Cookie&#xff09;是服务器发送到 用户浏览器并保存在浏览器上的一小块数据&#xff0c;它会在浏览器之后向同一服务器再次发 起请求时被携带并发送到服务器上。通常&#xff0c;它用于…...

安宝特科技 | AR眼镜在安保与安防领域的创新应用及前景

随着科技的不断进步&#xff0c;增强现实&#xff08;AR&#xff09;技术逐渐在多个领域展现出其独特的优势&#xff0c;尤其是在安保和安防方面。AR眼镜凭借其先进的功能&#xff0c;在机场、车站、海关、港口、工厂、园区、消防局和警察局等行业中为安保人员提供了更为高效、…...

2024 第十二届重庆国际植保双交会暨新型肥料农药产业博览会

2024 第十二届重庆国际植保双交会暨新型肥料农药产业博览会&#xff0c;引领农业新未来 农业&#xff0c;是人类生存的基石&#xff0c;是社会发展的保障。而肥料和农药&#xff0c;作为农业生产的重要投入品&#xff0c;其品质和技术的不断创新&#xff0c;直接关系着农业的可…...

用“说”智能控制灯具开关语音识别芯片NRK3603

用“说”智能控制灯具开关是一种基于语音识别技术的智能家居设备&#xff0c;它通过内置的语音识别芯片&#xff0c;利用离线识别算法&#xff0c;将用户的语音指令实现对灯具的控制&#xff0c;NRK3603语音识别芯片成为客户低成本的离线语音识别方案。 功能特性&#xff1a; …...

APS开源源码解读: 排程工具 optaplanner

抽象层次非常好&#xff0c;广义优化工具。用于排产没有复杂的落地示例 https://github.com/apache/incubator-kie-optaplanner/blob/main/optaplanner-examples/src/main/java/org/optaplanner/examples/projectjobscheduling/app/ProjectJobSchedulingApp.javahttps://github…...

AMEYA360:村田量产用于汽车市场的高可靠性0603M铜电极负温度系数NTC热敏电阻

株式会社村田制作所开发了0603M尺寸(0.60.30.3mm)铜电极负温度系数(NTC)热敏电阻&#xff0c;型号分别是“NCU03XH103F6SRL”和“NCU03XH103F60RL”&#xff0c;该新品扩充了NCU系列的产品尺寸阵容&#xff0c;满足了汽车市场应用中电路板的高密度化和小型化、以及对电子部件的…...

代码随想录第十天|150.逆波兰表达式求值 239.滑动窗口的最大值 347.前K个高频元素

150.逆波兰表达式求解 思路&#xff1a;做过 使用stoi &#xff1a;字符串转数字 class Solution { public:int cal(int num1,int num2,char c){int res;if(c){resnum1num2;}if(c-){resnum2-num1;}if(c*){resnum1*num2;}if(c/){resnum2/num1;}return res;}int evalRPN(vector…...

[阅读笔记]《解读基金—我的投资观与实践》— 季凯帆

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…...

2.3之前

1. 2. freertos基础时钟:freertos自动的采用systick定时器,作为freertos基础时钟&#xff0c;systick定时器只有定时中断功能&#xff0c;1ms中断一次。...

处理器基础知识——cache

本文节选自书籍《大话处理器&#xff1a;处理器基础知识读本》 PDF版本可以访问我的网盘通过网盘分享的文件&#xff1a;大话处理器&#xff1a;处理器基础知识读本.pdf 提取码: 1234 0 什么是 Cache 随处可见的Cache–技术来源于生活 使用电脑的人对 Cachc 并不会陌生&#…...

操作系统的运行环境

1.处理器的运行模式 目态 也叫用户态&#xff0c; 执行非特权指令&#xff1a;不能直接访问系统中的软硬件资源&#xff0c;仅仅可以访问用户地址空间。 用户应用程序运行在目态。 管态 也叫内核态&#xff0c; 可执行除访管指令外的任意指令&#xff0c;包括特权指令&…...

如何在 Selenium 中获取网络调用请求?

引言 捕获网络请求对于理解网站的工作方式以及传输的数据至关重要。Selenium 作为一种 Web 自动化工具,可以用于捕获网络请求。本文将讨论如何使用 Selenium 在 Java 中捕获网络请求并从网站检索数据。 我们可以使用浏览器开发者工具轻松捕获网络请求或日志。大多数现代 Web…...

IP学习——oneday

1.什么是网络&#xff1f;为什么需要网络&#xff1f; 空间&#xff0c;时间&#xff1b;传统的邮件传输要考虑到距离&#xff0c;网络解决了空间距离&#xff08;太远&#xff09;、解决了时间问题&#xff08;旧音乐等&#xff09; 云:面向客户的虚拟化服务 运营商公司主营…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...