OkHttp用法-Java调用http服务

news2025/5/17 5:16:53

特点:高性能,支持异步请求,连接池优化

官方文档:提供快速入门指南和高级功能(如拦截器、连接池)的详细说明,GitHub仓库包含丰富示例。

社区资源:中文教程丰富,GitHub高星标(40k+),社区活跃度高,问题响应快。

维护状态:由Square公司持续维护,更新频繁,支持最新TLS和HTTP/2特性。

// 1. 添加 Maven 依赖
// <dependency>
//     <groupId>com.squareup.okhttp3</groupId>
//     <artifactId>okhttp</artifactId>
//     <version>4.9.3</version>
// </dependency>

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class OkHttpExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://api.example.com/data")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String result = response.body().string();
                System.out.println("Response: " + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

OkHttp 核心用法详解(从基础到实战)

一、基础用法
1. 创建 OkHttpClient 实例
// 基础配置(可扩展代理、超时等)
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS) // 连接超时
    .readTimeout(30, TimeUnit.SECONDS)    // 读取超时
    .writeTimeout(30, TimeUnit.SECONDS)   // 写入超时
    .retryOnConnectionFailure(true)      // 连接失败自动重试
    .build();
2. 构建请求(GET 示例)
Request request = new Request.Builder()
    .url("https://api.example.com/data")
    .header("User-Agent", "OkHttp Example") // 添加请求头
    .get() // 默认是GET,可省略
    .build();
3. 发送请求
  • 同步请求(阻塞当前线程):

    try (Response response = client.newCall(request).execute()) {
        if (response.isSuccessful()) {
            String result = response.body().string();
            System.out.println("Response: " + result);
        } else {
            System.out.println("Error: " + response.code());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  • 异步请求(非阻塞,通过回调处理):

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                String result = response.body().string();
                System.out.println("Async Response: " + result);
            }
        }
    
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
    });
    
二、POST 请求与数据提交
1. 提交 JSON 数据
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

String jsonBody = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
RequestBody body = RequestBody.create(jsonBody, JSON);

Request request = new Request.Builder()
    .url("https://api.example.com/post")
    .post(body)
    .build();
2. 提交表单数据
RequestBody formBody = new FormBody.Builder()
    .add("username", "user")
    .add("password", "pass")
    .build();

Request request = new Request.Builder()
    .url("https://api.example.com/login")
    .post(formBody)
    .build();
三、文件上传与下载
1. 文件上传(Multipart)
File file = new File("path/to/file.jpg");
RequestBody fileBody = RequestBody.create(file, MediaType.parse("image/jpeg"));

RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", file.getName(), fileBody)
    .addFormDataPart("description", "Test upload")
    .build();

Request request = new Request.Builder()
    .url("https://api.example.com/upload")
    .post(requestBody)
    .build();
2. 文件下载
Request request = new Request.Builder()
    .url("https://api.example.com/file.zip")
    .build();

try (Response response = client.newCall(request).execute()) {
    if (response.isSuccessful()) {
        byte[] fileData = response.body().bytes();
        Files.write(Paths.get("downloaded.zip"), fileData);
    }
}
四、高级功能
1. 拦截器(Logging & Header 修改)
// 日志拦截器
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);

// 自定义 Header 拦截器
Interceptor headerInterceptor = chain -> {
    Request originalRequest = chain.request();
    Request newRequest = originalRequest.newBuilder()
        .header("Authorization", "Bearer token123")
        .build();
    return chain.proceed(newRequest);
};

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(logging)
    .addInterceptor(headerInterceptor)
    .build();
2. 连接池配置(优化性能)
ConnectionPool pool = new ConnectionPool(5, 5, TimeUnit.MINUTES); // 最大空闲连接5,保持5分钟
OkHttpClient client = new OkHttpClient.Builder()
    .connectionPool(pool)
    .build();
五、最佳实践
  1. 复用 OkHttpClient 实例:避免频繁创建/销毁,减少资源开销。
  2. 异步请求优先:在 Android 等 UI 线程受限环境中,必须使用异步请求。
  3. 合理配置超时:根据业务场景调整 connectTimeoutreadTimeout
  4. 使用拦截器统一处理:日志、错误重试、Header 添加等逻辑集中管理。
  5. 大文件下载用流式处理:避免 response.body().string() 导致内存溢出,改用 response.body().byteStream() 逐块读取。
六、常见问题
  • Q:如何取消正在进行的请求?
    A:调用 Call.cancel(),需在回调中检查 isCanceled()

  • Q:如何处理 HTTPS 证书问题?
    A:通过 CertificatePinner 配置证书固定,或自定义 X509TrustManager(需谨慎)。

  • Q:OkHttp 与 Retrofit 的关系?
    A:Retrofit 是基于 OkHttp 的 RESTful 客户端封装,提供更简洁的 API 调用方式。


通过以上内容,您已掌握 OkHttp 的核心用法,可根据项目需求灵活选择同步/异步请求、配置拦截器、优化连接池,实现高效稳定的网络通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day18-数据结构引言

一、 概述 数据结构&#xff1a;相互之间存在一种或多种特定关系的数据元素的集合。 1.1 特定关系&#xff1a; 1. 逻辑结构 2.物理结构&#xff08;在内存当中的存储关系&#xff09; 逻辑结构物理结构集合&#xff0c;所有数据在同一个集合中&#xff0c;关系平等顺…

我开源了一个免费在线工具!UIED Tools

UIED Tools - 免费在线工具集合 最近更新&#xff1a;修改了文档说明&#xff0c;优化了项目结构介绍 这是设计师转开发的第一个开源项目&#xff0c;bug和代码规范可能有些欠缺。 这是一个功能丰富的免费在线工具集合网站&#xff0c;集成了多种实用工具&#xff0c;包括 AI …

什么时候可以开始学习深度学习?

咱们先来聊聊机器学习和深度学习的关系~ 这个问题其实挺常见的&#xff0c;之前我也跟不少同事、同学聊过。最近有好几个同学也聊过。 简单说&#xff0c;深度学习是机器学习的一个子集&#xff0c;两者不是并列关系&#xff0c;而是“包含”关系。 你可以这么理解&#xff…

初学python的我开始Leetcode题8-5

提示&#xff1a;100道LeetCode热题-8-5主要是二叉树相关&#xff0c;包括三题&#xff1a;路径总和 III、二叉树的最近公共祖先、二叉树中的最大路径和。由于初学&#xff0c;所以我的代码部分仅供参考。 前言 二叉树完结撒花~ 下一次的图论会是一些有趣的应用案例~ 提示&am…

构建RAG混合开发---PythonAI+JavaEE+Vue.js前端的实践

写在前文&#xff1a;之所以设计这一套流程&#xff0c;是因为 Python在前沿的科技前沿的生态要比Java好&#xff0c;而Java在企业级应用层开发比较活跃&#xff1b; 毕竟许多企业的后端服务、应用程序均采用Java开发&#xff0c;涵盖权限管理、后台应用、缓存机制、中间件集成…

08.webgl_buffergeometry_attributes_none ,three官方示例+编辑器+AI快速学习

本实例主要讲解内容 这个Three.js示例展示了无属性几何体渲染技术&#xff0c;通过WebGL 2的gl_VertexID特性和伪随机数生成算法&#xff0c;在着色器中动态计算顶点位置和颜色&#xff0c;而不需要在CPU端预先定义几何体数据。 核心技术包括&#xff1a; WebGL 2的顶点ID特…

26考研 | 王道 | 计算机组成原理 | 一、计算机系统概述

26考研 | 王道 | 计算机组成原理 | 一、计算机系统概述 文章目录 26考研 | 王道 | 计算机组成原理 | 一、计算机系统概述1.1 计算机的发展1.2 计算机硬件和软件1.2.1 计算机硬件的基本组成1.2.2 各个硬件的工作原理1.2.3 计算机软件1.2.4 计算机系统的层次结构1.2.5 计算机系统…

LeetCode100.2 字母异位词分组

观察题目&#xff0c;需要把strs中的元素按照字母进行归类&#xff0c;一个朴素的思路是&#xff1a;遍历strs&#xff0c;对每个元素排序后插入哈希表中&#xff0c;随后再遍历一遍表将其转化为vector<vector<string>>。 class Solution { public:vector<vect…

显示的图标跟UI界面对应不上。

图片跟UI界面不符合。 要找到对应dp的值。UI的dp要跟代码里的xml文件里的dp要对应起来。 蓝湖里设置一个宽度给对应上。然后把对应的值填入xml. 一个屏幕上的图片到底是用topmarin来设置&#xff0c;还是用bottommarin来设置。 因为第一节&#xff0c;5&#xff0c;7 车厢的…

高并发内存池(三):TLS无锁访问以及Central Cache结构设计

目录 前言&#xff1a; 一&#xff0c;thread cache线程局部存储的实现 问题引入 概念说明 基本使用 thread cache TLS的实现 二&#xff0c;Central Cache整体的结构框架 大致结构 span结构 span结构的实现 三&#xff0c;Central Cache大致结构的实现 单例模式 thr…

在Taro中开发一个跨端Svg组件,同时支持小程序、H5、React Native

Taro系列中一直没有跨端的绘图工具&#xff0c;小程序端支持canvas但是不支持svg&#xff0c;RN端有 react-native-svg 支持svg&#xff0c;但是没有很好原生的canvas插件&#xff0c;社区的canvas都是基于WebView实现的&#xff0c;或者skia&#xff0c;这个插件的书写方式和c…

【办公类-100-01】20250515手机导出教学照片,自动上传csdn+最大化、最小化Vs界面

背景说明&#xff1a; 每次把教学照片上传csdn&#xff0c;都需要打开相册&#xff0c;一张张截图&#xff0c;然后ctrlV黏贴到CSDN内&#xff0c;我觉得太烦了。 改进思路&#xff1a; 是否可以先把所有照片都上传到csdn&#xff0c;然后再一张张的截图&#xff08;去掉幼儿…

Python零基础入门到高手8.4节: 元组与列表的区别

目录 8.4.1 不可变数据类型 8.4.2 可变数据类型 8.4.3 元组与列表的区别 8.4.4 今天彩票没中奖 8.4.1 不可变数据类型 不可变数据类型是指不可以对该数据类型进行原地修改&#xff0c;即只读的数据类型。迄今为止学过的不可变数据类型有字符串&#xff0c;元组。 在使用[]…

深度学习入门:深度学习(完结)

目录 1、加深网络1.1 向更深的网络出发1.2 进一步提高识别精度1.3 加深层的动机 2、深度学习的小历史2.1 ImageNet2.2 VGG2.3 GoogleNet2.4 ResNet 3、深度学习的高速化3.1 需要努力解决的问题3.2 基于GPU的高速化3.3 分布式学习3.4 运算精度的位数缩减 4、深度学习的应用案例4…

使用Scrapeless Scraping Browser的自动化和网页抓取最佳实践

引言&#xff1a;人工智能时代浏览器自动化和数据收集的新范式 随着生成性人工智能、人工智能代理和数据密集型应用程序的快速崛起&#xff0c;浏览器正在从传统的“用户互动工具”演变为智能系统的“数据执行引擎”。在这一新范式中&#xff0c;许多任务不再依赖单一的API端点…

java数组题(5)

&#xff08;1&#xff09;&#xff1a; 思路&#xff1a; 1.首先要对数组nums排序&#xff0c;这样两数之间的差距最小。 2.题目要求我们通过最多 k 次递增操作&#xff0c;使数组中某个元素的频数&#xff08;出现次数&#xff09;最大化。经过上面的排序&#xff0c;最大数…

物联网无线传感方向专业词汇解释

涡旋电磁波(VEMW)&#xff1a;一种具有轨道角动量的电磁波&#xff0c;其特性在于能够在传播过程中携带额外的相位信息&#xff0c;从而增加通信系统的容量和灵活性。波前&#xff1a;波动传播过程中&#xff0c;同一时刻振动相位相同的所有点构成的几何曲面&#xff0c;代表波…

Maven 插件参数注入与Mojo开发详解

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

2024年全国青少年信息素养大赛——算法创意实践挑战赛复赛真题(小学组)——玫瑰花地的面积

2024年全国青少年信息素养大赛——算法创意实践挑战赛复赛真题(小学组)——玫瑰花地的面积 上面试卷可点下方&#xff0c;支持在线编程&#xff0c;在线测评&#xff5e; 2024年全国信息素养大赛 算法创意实践挑战赛复赛(小学组)_c_少儿编程题库学习中心-嗨信奥 5月17号 全国青…

【补充笔记】修复“NameError: name ‘ZhNormalizer‘ is not defined”的直接方法

#工作记录 一、问题描述 在运行CosyVoice_For_Windows项目时&#xff0c;出现以下报错&#xff1a; File "F:\PythonProjects\CosyVoice_For_Windows\cosyvoice\cli\frontend.py", line 74, in __init__ self.zh_tn_model ZhNormalizer(remove_erhuaFalse, fu…