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

2024-09-05 18:12

本文主要是介绍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使用详细教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139695

相关文章

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加