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

OkHttp3实战:除了GET和POST,你还能用它轻松搞定文件上传和Session保持

OkHttp3实战解锁文件上传与Session保持的高级技巧在移动应用开发中网络请求是几乎所有功能的基础支撑。OkHttp3作为Android平台上最受欢迎的HTTP客户端库之一其简洁的API设计和强大的功能让开发者能够轻松处理各种网络请求场景。但很多开发者仅仅停留在GET和POST的基础使用上未能充分挖掘OkHttp3的潜力。本文将深入探讨两个实际开发中高频出现的需求文件上传和Session保持展示如何利用OkHttp3优雅地解决这些问题。1. 构建高效的文件上传功能文件上传是社交类App中常见的功能需求比如用户头像更换、图片分享等场景。OkHttp3通过MultipartBody提供了简洁而强大的文件上传支持。1.1 Multipart/form-data请求的构建不同于普通的表单提交文件上传需要构造multipart/form-data类型的请求体。OkHttp3的MultipartBody.Builder让这个过程变得异常简单// 创建MultipartBody.Builder实例 MultipartBody.Builder builder new MultipartBody.Builder() .setType(MultipartBody.FORM); // 添加文本参数 builder.addFormDataPart(username, user123); builder.addFormDataPart(description, 用户头像); // 添加文件参数 File avatarFile new File(/path/to/avatar.jpg); builder.addFormDataPart(avatar, avatarFile.getName(), RequestBody.create(MediaType.parse(image/jpeg), avatarFile)); // 构建完整的请求体 MultipartBody requestBody builder.build();关键点说明setType(MultipartBody.FORM)设置内容类型为multipart/form-dataaddFormDataPart方法既可以添加普通文本参数也可以添加文件参数文件参数需要指定文件名和媒体类型(MediaType)1.2 处理大文件上传与进度监听在实际应用中特别是上传大文件时用户需要了解上传进度。OkHttp3通过拦截器机制可以轻松实现上传进度监听// 自定义进度监听RequestBody class ProgressRequestBody extends RequestBody { private final File file; private final ProgressListener listener; public ProgressRequestBody(File file, ProgressListener listener) { this.file file; this.listener listener; } Override public void writeTo(BufferedSink sink) throws IOException { long total contentLength(); long uploaded 0; try (Source source Okio.source(file)) { Buffer buffer new Buffer(); long read; while ((read source.read(buffer, 2048)) ! -1) { sink.write(buffer, read); uploaded read; listener.onProgress(uploaded, total); } } } } // 使用自定义RequestBody builder.addFormDataPart(video, videoFile.getName(), new ProgressRequestBody(videoFile, (uploaded, total) - { float progress uploaded * 100f / total; Log.d(Upload, Progress: progress %); }));2. 实现可靠的Session保持机制在需要用户认证的应用中保持会话状态是基本需求。OkHttp3通过CookieJar接口提供了灵活的Cookie管理方案。2.1 配置持久化CookieJarOkHttp3本身不提供Cookie的持久化存储但我们可以轻松实现自己的CookieJarpublic class PersistentCookieJar implements CookieJar { private final SharedPreferences preferences; public PersistentCookieJar(Context context) { preferences context.getSharedPreferences(CookiePrefs, Context.MODE_PRIVATE); } Override public void saveFromResponse(HttpUrl url, ListCookie cookies) { SharedPreferences.Editor editor preferences.edit(); for (Cookie cookie : cookies) { editor.putString(cookie.name(), cookie.toString()); } editor.apply(); } Override public ListCookie loadForRequest(HttpUrl url) { ListCookie cookies new ArrayList(); MapString, ? allCookies preferences.getAll(); for (Map.EntryString, ? entry : allCookies.entrySet()) { Cookie cookie Cookie.parse(url, entry.getValue().toString()); if (cookie ! null cookie.matches(url)) { cookies.add(cookie); } } return cookies; } } // 配置OkHttpClient使用自定义CookieJar OkHttpClient client new OkHttpClient.Builder() .cookieJar(new PersistentCookieJar(context)) .build();2.2 处理Session过期与自动刷新在实际应用中Session可能会过期需要自动刷新。我们可以通过拦截器实现这一逻辑public class AuthInterceptor implements Interceptor { private final Context context; public AuthInterceptor(Context context) { this.context context; } Override public Response intercept(Chain chain) throws IOException { Request request chain.request(); Response response chain.proceed(request); // 检查401未授权响应 if (response.code() 401) { // 刷新token String newToken refreshToken(); // 使用新token重试请求 Request newRequest request.newBuilder() .header(Authorization, Bearer newToken) .build(); return chain.proceed(newRequest); } return response; } private String refreshToken() throws IOException { // 实现token刷新逻辑 // ... } } // 配置拦截器 OkHttpClient client new OkHttpClient.Builder() .addInterceptor(new AuthInterceptor(context)) .build();3. 高级配置与性能优化OkHttp3提供了丰富的配置选项合理设置可以显著提升应用性能。3.1 连接池与超时设置OkHttpClient client new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) // 连接超时 .readTimeout(30, TimeUnit.SECONDS) // 读取超时 .writeTimeout(30, TimeUnit.SECONDS) // 写入超时 .connectionPool(new ConnectionPool( 5, // 最大空闲连接数 5, // 保持时间(分钟) TimeUnit.MINUTES)) .build();推荐配置参数参数默认值推荐值说明connectTimeout10s15s适用于移动网络波动readTimeout10s30s文件上传下载适当延长writeTimeout10s30s大文件上传需要更长时间maxIdleConnections55-10根据并发请求量调整3.2 缓存策略配置// 配置缓存目录和大小 int cacheSize 10 * 1024 * 1024; // 10MB Cache cache new Cache(context.getCacheDir(), cacheSize); OkHttpClient client new OkHttpClient.Builder() .cache(cache) .addNetworkInterceptor(new CacheInterceptor()) .build(); // 自定义缓存拦截器 class CacheInterceptor implements Interceptor { Override public Response intercept(Chain chain) throws IOException { Response originalResponse chain.proceed(chain.request()); return originalResponse.newBuilder() .header(Cache-Control, public, max-age3600) // 1小时缓存 .build(); } }4. 实战社交App中的完整示例让我们结合社交App的实际场景实现一个完整的用户头像上传和会话保持方案。4.1 用户头像上传实现public class AvatarUploader { private final OkHttpClient client; public AvatarUploader(Context context) { this.client new OkHttpClient.Builder() .cookieJar(new PersistentCookieJar(context)) .addInterceptor(new AuthInterceptor(context)) .build(); } public void uploadAvatar(File avatarFile, UploadCallback callback) { MultipartBody requestBody new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart(action, upload_avatar) .addFormDataPart(avatar, avatarFile.getName(), new ProgressRequestBody(avatarFile, callback::onProgress)) .build(); Request request new Request.Builder() .url(https://api.socialapp.com/user/avatar) .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { Override public void onFailure(Call call, IOException e) { callback.onError(e); } Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { callback.onSuccess(); } else { callback.onError(new IOException(Upload failed)); } } }); } public interface UploadCallback { void onProgress(long uploaded, long total); void onSuccess(); void onError(Exception e); } }4.2 会话管理的完整实现public class SessionManager { private static final String SESSION_COOKIE sessionid; private final OkHttpClient client; private final PersistentCookieJar cookieJar; public SessionManager(Context context) { this.cookieJar new PersistentCookieJar(context); this.client new OkHttpClient.Builder() .cookieJar(cookieJar) .addInterceptor(new AuthInterceptor(context)) .build(); } public void login(String username, String password, LoginCallback callback) { FormBody formBody new FormBody.Builder() .add(username, username) .add(password, password) .build(); Request request new Request.Builder() .url(https://api.socialapp.com/login) .post(formBody) .build(); client.newCall(request).enqueue(new Callback() { Override public void onFailure(Call call, IOException e) { callback.onError(e); } Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { callback.onSuccess(); } else { callback.onError(new IOException(Login failed)); } } }); } public boolean isLoggedIn() { // 检查是否存在有效的session cookie ListCookie cookies cookieJar.loadForRequest( HttpUrl.parse(https://api.socialapp.com)); for (Cookie cookie : cookies) { if (cookie.name().equals(SESSION_COOKIE) !cookie.expiresAt() System.currentTimeMillis()) { return true; } } return false; } public interface LoginCallback { void onSuccess(); void onError(Exception e); } }在实际项目中使用OkHttp3处理文件上传和会话管理时有几个经验值得分享首先对于文件上传一定要在服务器端做好文件类型和大小的验证其次会话管理要注意安全使用HttpOnly和Secure标记的Cookie最后合理配置超时时间和重试策略可以显著提升移动网络下的用户体验。

相关文章:

OkHttp3实战:除了GET和POST,你还能用它轻松搞定文件上传和Session保持

OkHttp3实战:解锁文件上传与Session保持的高级技巧 在移动应用开发中,网络请求是几乎所有功能的基础支撑。OkHttp3作为Android平台上最受欢迎的HTTP客户端库之一,其简洁的API设计和强大的功能让开发者能够轻松处理各种网络请求场景。但很多开…...

一份不到 70 行的 Markdown,凭什么一周冲上 GitHub 趋势榜首?

JeecgBoot AI专题研究 | andrej-karpathy-skills:给 AI 编程立规矩,外加一分钟安装指南 一个反常识的 GitHub 现象 最近 GitHub 趋势周榜的第一名,不是新框架,也不是新模型,而是一份不到 70 行的 Markdown 文件——项…...

zabbixwatch 安装部署

目录 环境要求 一、新系统搭建 1. 安装 Docker 环境 2. 下载项目文件 3. 启动服务 5. 配置数据源 二、系统卸载 完全卸载(删除所有数据) 仅停止服务(保留数据) 该插件可与zabbix进行数据连通,形成对应的数据大…...

电赛电源模块“内卷”新思路:用这颗国产LDO替换TPS7A4501,成本直降30%且性能不输

电赛电源模块国产替代实战:如何用高性能LDO实现30%降本 全国电子设计竞赛中,电源模块的稳定性和成本控制一直是参赛团队的核心痛点。当TI的TPS7A4501等进口LDO面临价格波动和交期延长时,寻找性能相当且引脚兼容的国产替代方案成为破局关键。本…...

ESXi 6.7存储认不到?手把手教你排查并更换Emulex LPe12000 HBA驱动(附完整命令)

ESXi 6.7存储识别故障深度排查:从HBA驱动诊断到安全替换实战指南 当你面对一台ESXi主机"看得见却吃不着"存储的诡异状况时,那种焦虑感我深有体会。存储阵列显示WWN映射正常,交换机端口状态绿灯常亮,但ESXi就是倔强地拒…...

手把手教你用Flink SQL调优Paimon分桶:避开数据倾斜,Join性能提升5倍

Flink SQL实战:Paimon分桶策略如何让实时数据湖性能飙升 在实时数据湖架构中,Paimon作为流批一体的存储解决方案,其分桶机制直接影响着数据写入效率与查询性能。许多团队在初期搭建数据湖时,往往只关注基础功能的实现,…...

PyCharm添加解释器找不到mayapy怎么办?

在PyCharm中添加解释器时若提示找不到mayapy.exe,通常是因为路径未正确指定或环境变量未配置。首先需确认Maya已完整安装,并手动定位到默认安装目录(如C:\Program Files\Autodesk\Maya202X\bin)检查mayapy.exe是否存在。在PyCharm…...

别再傻傻全量引入antd了!React项目用craco+less-loader搞定按需加载与主题定制(附最新版本避坑指南)

2023终极方案:用cracoless-loader实现antd按需加载与主题定制 在React生态中,antd作为企业级UI库的标杆,其丰富的组件和设计语言深受开发者喜爱。但随着项目规模扩大,全量引入antd带来的性能问题逐渐显现——一个中型项目仅antd样…...

避坑指南:Unity ShaderGraph做旋涡效果,别忘了设置Transparent和Alpha通道!

Unity ShaderGraph旋涡效果实战:透明通道与遮罩的黄金法则 当你在Unity中第一次看到那些酷炫的旋涡特效时,是否也曾被它们流畅的透明过渡和动态旋转所吸引?作为视觉表现的关键元素,旋涡效果广泛应用于游戏中的传送门、魔法阵、能量…...

别再为后端数据格式发愁了!vue-treeselect的normalizer属性保姆级配置指南

别再为后端数据格式发愁了!vue-treeselect的normalizer属性保姆级配置指南 树形选择器在前端开发中应用广泛,但后端返回的数据结构往往与组件要求不匹配。vue-treeselect作为Vue生态中最受欢迎的树形选择组件,其normalizer属性正是解决这一痛…...

告别模拟信号:手把手教你用示波器解析汽车传感器的SENT协议数据帧

告别模拟信号:手把手教你用示波器解析汽车传感器的SENT协议数据帧 在汽车电子系统的调试现场,工程师们常常需要面对各种传感器信号的解析难题。当传统的模拟信号逐渐被数字协议取代,SENT(Single Edge Nibble Transmission&#xf…...

TinyMCE 6.x 在Vue 3 + Vite项目中的完整配置与避坑指南(2024最新)

TinyMCE 6.x 在Vue 3 Vite项目中的完整配置与避坑指南(2024最新) 当Vue 3遇上Vite,前端开发体验迎来了质的飞跃。但在这个现代化工具链中集成TinyMCE 6.x这样的富文本编辑器时,很多开发者发现老教程已经不再适用。本文将带你从零…...

六大AI企业服务全景解析:技术路线、核心优势与企业选型指南

六大AI企业服务全景解析:技术路线、核心优势与企业选型指南在大模型应用全面落地的当下,企业AI服务不再局限于单一的模型调用,而是朝着专业化、场景化、合规化、高可控方向细分。不同厂商基于差异化技术架构与路线,形成了各自的核…...

FinalShell高级版激活避坑指南:离线激活后哪些功能真的能用?

FinalShell高级版离线激活后的功能实测:哪些功能真正解锁? 最近在技术社区看到不少关于FinalShell高级版离线激活的讨论,很多用户按照教程操作后,虽然界面显示"已激活高级版",但实际使用时却发现部分功能仍然…...

不只为质押:聊聊在AWS/Ali云服务器上搭建ETH全节点的几种实际用途与成本考量

在AWS/Ali云服务器上搭建ETH全节点的非质押应用场景与成本效益分析 当开发者考虑运行一个以太坊全节点时,第一反应往往是"这需要质押32个ETH吗?"——实际上,非质押的全节点同样能带来丰富的实际价值。本文将跳出技术搭建细节&#…...

避坑指南:在UnityXFramework中集成热更新与多语言,我踩过的那些‘坑’(ToLua/AssetBundle实战)

UnityXFramework热更新与多语言集成实战避坑指南 1. 热更新资源依赖的连环陷阱 在UnityXFramework中实现热更新功能时,资源依赖管理是最容易踩坑的环节之一。许多开发者在项目中期引入热更新后,会发现明明只修改了少量资源,却导致整个AssetBu…...

AI时代工程师“超能力”进化论:键盘敲得再快,也怕AI念咒

摘要:当 GitHub Copilot 能在一分钟内写完你一天的代码量时,工程师的核心竞争力发生了什么变化?本文探讨从“人形编译器”到“AI 驯兽师”的进化路径,盘点新时代工程师必须点亮的三种终极超能力。一、 引言:旧日荣光的…...

用旧投影仪和普通摄像头DIY结构光扫描仪:3D Scanning Software实战建模全记录

用旧投影仪和普通摄像头DIY结构光扫描仪:3D Scanning Software实战建模全记录 当创客精神遇上三维重建技术,一台闲置的投影仪加上普通USB摄像头就能变身专业级扫描设备。这种低成本结构光方案在开源软件加持下,精度足以满足手办复制、零件逆向…...

Windows Cleaner终极指南:3步快速解决C盘爆红,免费释放20GB空间

Windows Cleaner终极指南:3步快速解决C盘爆红,免费释放20GB空间 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner Windows Cleaner是一款开源…...

从华为LTC到企业核心流程:聊聊SAP OTC/PTP如何融入大流程框架

从华为LTC到企业核心流程:SAP OTC/PTP如何融入大流程框架 在数字化转型的浪潮中,企业流程治理正经历着从职能导向到价值导向的深刻变革。当我们谈论SAP系统中的OTC(Order to Cash)或PTP(Procure to Pay)时&…...

告别混乱!用Fiori磁贴组和目录高效管理你的SAP业务应用入口

告别混乱!用Fiori磁贴组和目录高效管理你的SAP业务应用入口 当企业SAP Fiori应用数量突破三位数时,用户最常抱怨的不是功能缺失,而是"根本找不到需要的应用"。某制造业CIO曾向我展示他们的Fiori门户——287个应用像超市货架上的商品…...

用Open3D处理点云数据?从“灯.pcd”开始你的第一个3D数据分析项目

用Open3D处理点云数据:从“灯.pcd”开启3D分析实战 当你第一次面对三维点云数据时,那种密密麻麻的坐标点阵可能让人望而生畏。但别担心,Open3D就像给你的3D数据配了一副智能眼镜——它能将这些抽象的数字转化为可视化的立体世界。今天我们就用…...

ROS与ABB机器人联调:如何通过RoboStudio信号与系统输出来实时监控机器人状态

ROS与ABB机器人联调实战:RoboStudio信号监控与系统输出深度解析 在工业机器人开发领域,ROS与ABB机器人的联调一直是工程师们关注的焦点。当基础通信建立后,如何实时掌握机器人内部状态成为提升调试效率的关键。本文将带您深入探索RoboStudio中…...

告别Conda安装噩梦:一份保姆级的PyTorch(CPU版)环境搭建避坑指南

告别Conda安装噩梦:一份保姆级的PyTorch(CPU版)环境搭建避坑指南 刚接触深度学习的开发者们,十有八九会在环境搭建这一步踩坑。尤其是当你兴冲冲地按照PyTorch官网的安装指南操作,却在Anaconda Prompt里遭遇一连串红色…...

线性规划里的大M到底怎么设?一个生产排程的实例,带你避开数值计算的坑

线性规划中的大M取值艺术:从生产排程实战看数值稳定性 想象一下,你正为一家小型电子厂设计下周的生产计划。工厂需要生产两种型号的智能手表——基础版和高级版,每种产品对生产线工时、原材料消耗的要求不同,而你的目标是最大化总…...

torch.cuda.is_available()返回False?手把手教你从驱动到环境逐项排查

深度学习环境配置:系统性解决PyTorch GPU识别问题全指南 当你在终端输入torch.cuda.is_available(),期待看到True却得到False时,那种挫败感每个深度学习开发者都深有体会。这不是简单的安装问题,而是涉及驱动、环境、版本匹配等多…...

10、Docker容器故障排查

Docker 容器故障排查详细步骤 一、基础检查流程 1. 服务状态检查 # 检查Docker服务运行状态 systemctl status docker service docker status # 适用于旧版本系统# 检查Docker守护进程健康状态 docker info # 若正常会返回系统信息,异常则显示错误# 查看容器状态摘…...

EF Core 10向量扩展生产就绪 checklist(含A/B测试分流、向量维度漂移监控、fallback降级开关)

第一章:EF Core 10向量扩展生产就绪全景概览EF Core 10 向量扩展(Vector Extensions)并非官方内置功能,而是由社区驱动、经微软认可的高性能向量计算增强方案,专为 AI 原生应用与嵌入式相似性搜索场景设计。它深度集成…...

智慧校园平台中免费技术实现与应用分析

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…...

8、Docker镜像瘦身

Docker镜像瘦身 一、 常见docker镜像瘦身方法 在 Docker 镜像瘦身方面,有多种工具和技术可以帮助你显著减小镜像体积,提升构建和部署效率。以下是常用的工具和方法: 1. 基础优化方法 ① 多阶段构建(Multi-stage Builds&#xf…...