Android:OkHttp网络请求框架的使用

目录

一,OkHttp简介

二,OkHttp请求处理流程

三,OkHttp环境配置

四,OkHttp的使用

1.get网络请求

2.post上传表单数据

3.post上传json格式数据

4.文件上传

5.文件下载


一,OkHttp简介

        OkHttp是square公司推出的一款Android和Java网络请求库,是目前公认的最好用的网络请求框架,OkHttp有以下的特点:

  1. 支持Http/2,允许对同一主机的所有请求共享同一套接字;
  2. 使用连接池减少请求延时;
  3. 透明的GZIP压缩减少响应数据的大小;
  4. 缓存响应的内容,避免重复请求;

OkHttp源码地址:https://github.com/square/okhttp 

二,OkHttp请求处理流程

(1)使用OkHttp需要先创建OkHttpClient对象,可以使用构造器直接创建,也可以使用builder创建;

(2)使用Request.builder创建Request请求,用于封装要访问的网络地址Url。当进行post操作时,还需创建RequestBody用于封装请求数据,并调用Requst的post方法;

(3)通过OkHttpClient的newCall方法创建Call对象,使用同步或异步的方法发送Request请求,并接收Response响应数据;

三,OkHttp环境配置

(1)在build.gradle中添加依赖:

dependencies {
        implementation 'com.squareup.okhttp3:okhttp:3.14.9'
}

(2)在AndroidManifest.xml中添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET"/> 

(3)在AndroidManifest.xml添加 android:usesCleartextTraffic="true" 解除Http访问禁制:

四,OkHttp的使用

OkHttp主要有以下功能:

  1. get,post请求文本数据;
  2. 上传文件;
  3. 下载文件;
  4. 加载图片(自动压缩图片大小);

1.get网络请求

private void visitInternet() {//1.创建HttpClient对象OkHttpClient okHttpClient = new OkHttpClient();//2.获取request对象Request.Builder builder = new Request.Builder().url("https://www.bilibili.com/");Request request = builder.build();//3.获取call对象Call call = okHttpClient.newCall(request);//4.执行网络操作(同步)try {//同步执行网络操作Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

        注意这里使用了call的同步请求方式,会产生阻塞,所以此方法必须放在子线程中执行。如果不想放在子线程中执行的话,可以使用call的异步请求方式。

        当请求成功时call会返回Response,我们可以通过response.body()获取字符串,输入流等返回的信息。

2.post上传表单数据

        当需要上传数据时,需要创建RequestBody用于封装数据,因为我们这里上传的是表单数据,所以需要创建RequestBody的子类FormBody 。

private void postForm() {OkHttpClient okHttpClient = new OkHttpClient();//创建FormBody对象,封装数据(键值对信息)FormBody formBody = new FormBody.Builder().add("userName", "json").add("pwd", "123456").build();Request request = new Request.Builder().post(formBody).url(Host + "/servlet01").build();Call call = okHttpClient.newCall(request);//异步执行网络操作call.enqueue(new Callback() {//请求本身失败时调用@Overridepublic void onFailure(Call call, IOException e) {showResultOnUiThread("请求为空");}//请求成功时调用@Overridepublic void onResponse(Call call, Response response) throws IOException {String result = response.body().string();showResultOnUiThread(result);}});
}

        当使用call的异步请求方式时,需要重写两个方法onFailureonResponse,当请求失败时(连接失败或读写超时)调用onFailure,请求成功时调用onResponse。

        可以写一个简单的服务端来验证一下是否可以请求成功:

@WebServlet("/servlet01")
public class servlet01 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");String userName = req.getParameter("userName");String pwd = req.getParameter("pwd");if(userName == null || "".equals(userName)){resp.getWriter().write("用户名不能为空");}else if(pwd == null || "".equals(pwd)){resp.getWriter().write("密码不能为空");}else {resp.getWriter().write("欢迎:" + userName);}}
}

3.post上传json格式数据

        使用Gson需要先添加依赖:

implementation'com.google.code.gson:gson:2.10.1'

        当上传json数据时,自然需要用到RequestBody来封装json数据,同时还需用MediaType来设置数据类型(也就是我们想要上传的数据的类型)。

private void postJson() {OkHttpClient okHttpClient = new OkHttpClient();//1.创建json数据User user = new User();user.setUsername("json");user.setPwd("123456");String json = new Gson().toJson(user);//2.通过RequestBody封装json数据RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),//设置数据类型json//数据);Request request = new Request.Builder().post(requestBody).url(Host + "/servlet02").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

同样写一个简单服务端来测试一下:

@WebServlet("/servlet02")
public class servlet02 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(req.getInputStream()));String data = bufferedReader.readLine();resp.getWriter().write("json:" + data);}
}

4.文件上传

        通过OkHttp上传文件的步骤与上传json数据一致,只需更换设置的数据类型即可。因为上传的需要是安卓客户端的数据,所以我们需要先在安卓客户端添加数据。

        打开路径data/data/com.example.okhttp/files,在files目录下添加一张图片,之后就可以开始上传了。第一次打开时没有files这个目录,需要手动创建。

同时还需要给app添加访问sd卡的权限,在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

客户端上传文件:

private void upImg() {//通过文件路径打开文件String path = getFilesDir().getAbsolutePath() +"/zj.png";File file = new File(path);OkHttpClient okHttpClient = new OkHttpClient();RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"),file);Request request = new Request.Builder().post(requestBody).url(Host + "/servlet02").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();String result = response.body().string();showResultOnUiThread(result);} catch (IOException e) {throw new RuntimeException(e);}
}

服务端接收文件:

@WebServlet("/servlet02")
public class servlet02 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");File file = new File(filePath);ServletInputStream inputStream = req.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream(file);byte[] bytes = new byte[1024];int len = -1;while((len = inputStream.read(bytes)) != -1){fileOutputStream.write(bytes, 0, len);fileOutputStream.flush();}resp.getWriter().write("上传成功!");inputStream.close();fileOutputStream.close();}
}

5.文件下载

下载文件时不需要上传数据,因此不用创建RequestBody对象,只需发送请求即可。

private void downImg() {OkHttpClient okHttpClient = new OkHttpClient();Request request = new Request.Builder().url(Host2 + "/servlet03").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();//获取返回的输入流InputStream inputStream = response.body().byteStream();//转成bitmap数据Bitmap bitmap = BitmapFactory.decodeStream(inputStream);runOnUiThread(new Runnable() {@Overridepublic void run() {img_img.setImageBitmap(bitmap);}});} catch (IOException e) {throw new RuntimeException(e);}
}

服务端提供数据:

@WebServlet("/servlet03")
public class servlet03 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {File file = new File(filePath);ServletOutputStream outputStream = resp.getOutputStream();BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));byte[] bytes = new byte[1024];int len = -1;while((len = bufferedInputStream.read(bytes)) != -1){bufferedOutputStream.write(bytes, 0, len);}bufferedOutputStream.close();bufferedInputStream.close();}
}

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

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

相关文章

npm 源管理工具 nrm

npm 源管理工具 nrm 安装(可能很慢, 多试几次) npm install -g nrm查看可选择源列表 nrm ls切换源 nrm use <registry>如: nrm use taobao

rust的版本问题,安装问题,下载问题

rust的版本、安装、下载问题 rust版本问题&#xff0c; 在使用rust的时候&#xff0c;应用rust的包&#xff0c;有时候包的使用和rust版本有关系。 error: failed to run custom build command for pear_codegen v0.1.2 Caused by: process didnt exit successfully: D:\rus…

鸿蒙全面开发指南:入门、生态安全与资源支持

鸿蒙全面开发指南&#xff1a;入门、生态安全与资源支持 本文全面梳理了鸿蒙操作系统的开发入门流程&#xff0c;涵盖了开发环境准备、工具使用、项目创建、模拟器配置到应用安全设计的各个方面。通过本文&#xff0c;读者不仅能够了解鸿蒙开发的基本步骤&#xff0c;也能深入理…

Aspose.PDF功能演示:在 JavaScript 中将 TXT 转换为 PDF

您是否正在寻找一种在 JavaScript 项目中将纯文本文件从TXT无缝转换为PDF格式的方法&#xff1f;您来对地方了&#xff01;无论您是要构建 Web 应用程序、创建生产力工具&#xff0c;还是只是希望简化工作流程&#xff0c;直接从 JavaScript 代码中将 TXT 转换为 PDF 的功能都可…

第3天 Web源码拓展_小迪网络安全笔记

1.关于web源码目录结构 #数据库配置文件 后台目录 模板目录 数据库目录 1.1数据库配置文件: 1.1就拿wordpress来说,先到官网下载源码:Download – WordPress.org,解压源码之后: 2.2找到目录下名为 wp-config-sample.php的文件,这就是数据库配置文件: 设想: 我们在渗透…

FOURIER NEURAL OPERATOR FOR PARAMETRIC PARTIAL DIFFERENTIAL EQUATIONS

参数偏微分方程的傅里叶神经算子 论文链接&#xff1a;https://arxiv.org/abs/2010.08895 项目链接&#xff1a;https://github.com/neuraloperator/neuraloperator 作者博客&#xff1a;https://zongyi-li.github.io/blog/2020/fourier-pde/ 参数偏微分方程的傅里叶神经算子…

本地部署Terraria泰拉瑞亚私服并通过内网穿透生成公网地址远程联机

文章目录 前言1. 下载Terraria私服2. 本地运行Terraria 私服3. 本地Terraria私服连接4. Windwos安装Cpolar 工具5. 配置Terraria远程联机地址6. Terraria私服远程联机7. 固定远程联机地址8. 固定的联机地址测试 前言 本文将为你详细介绍在本地如何运行泰拉瑞亚本地私服和结合C…

认识 React Hooks

回顾函数组件 函数组件 没有组件实例 不能监听各个生命周期 无法扩展属性和方法 没有 state 和 setState 只是输入 props &#xff0c;输出 jsx &#xff0c;纯函数。 // class 组件class List extends React.Component {constructor(props) {super(props)}render() {con…

信息泄露--注意点点

目录 明确目标: 信息泄露: 版本软件 敏感文件 配置错误 url基于文件: url基于路由: 状态码: http头信息泄露 报错信息泄露 页面信息泄露 robots.txt敏感信息泄露 .get文件泄露 --判断: 搜索引擎收录泄露 BP: 爆破: 明确目标: 失能 读取 写入 执行 信息泄…

【文末附gpt升级方案】Ilya离开OpenAI内幕探究:算力削减与商业优先策略的冲突

Ilya离开OpenAI内幕探究&#xff1a;算力削减与商业优先策略的冲突 一、引言 在人工智能&#xff08;AI&#xff09;领域的飞速发展中&#xff0c;OpenAI一直以其领先的技术和创新产品而备受瞩目。然而&#xff0c;近日发生的Ilya Sutskever离开OpenAI的事件却引起了业界的广…

java企业级云MES系统全套源码,支持app、小程序、H5、台后管理

企业级云MES全套源码&#xff0c;支持app、小程序、H5、台后管理端 企业级智能制造MES系统源码&#xff0c;技术架构&#xff1a;springboot vue-element-plus-admin MES指的是制造企业生产过程执行系统&#xff0c;是一套面向制造企业车间执行层的生产信息化管理系统。MES可以…

栈(基于动态顺序表实现的栈)

栈的简单介绍 关于栈的性质咳咳 栈&#xff1a;栈是一种特殊的线性表,其中只让在一端插入和删除元素。 后进先出 进行插入删除的那一端叫栈顶&#xff0c;另一端叫栈底 我们实现的栈是基于一个动态顺序表的的栈&#xff0c;会实现栈的 入栈&#xff0c;出栈&#xff0c;获取…

修改默认时区,默认语言,默认国家

确认时区&#xff0c;语言&#xff0c;国家 build/make/target/product/languages_default.mkframeworks/base/packages/SettingsLib/res/xml/timezones.xml设备mk中添加相关内容 PRODUCT_PROPERTY_OVERRIDES \persist.sys.timezoneEurope/AmsterdamPRODUCT_PROPERTY_OVERRI…

嵌入式学习——3——超时timeout

1、自带超时参数的函数 select自带超时 定义超时时间变量 struct timeval tv {5, 0}; while(1) { tv.tv_sec 5; tv.tv_usec 0; int res select(1, &readfds, NULL, NULL, &tv); ..... } poll自带超时 1、poll函数的第三个参数&#xff0c;是以毫秒为单位的超时时间…

前端vue用el-table如何实现表头内容过长换行处理,实现换行效果

前端vue用el-table如何实现表头内容过长换行处理&#xff0c;实现换行效果 这是效果图 有两种方法&#xff0c;一种简易版本&#xff0c;一种万能方法,都是el-table&#xff0c;先看文档 表头标题是可以自定义的 方法一 label的解释写在代码里面了&#xff0c;这里会自动形成换…

Python概述

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 了解Python Python&#xff0c;本义是指“蟒蛇”。1989年&#xff0c;荷兰人Guido van Rossum发明了一种面向对象的解释型高级编程语言&#xff0c;…

利用神经网络学习语言(六)——总结与常见面试问题

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 文章列表&#xff1a; 利用神经网络学习语言&#xff08;一&#xff09;——自然语言处理的基本要素利用神经网络学习语言&…

Java基础入门day49

day49 tomcat 启动 进入tomcat的bin目录&#xff0c;双击或者运行startup.bat文件启动tomcat 控制台最后出现服务器启动在多少毫米之内&#xff0c;代表服务器成功启动 org.apache.catalina.startup.Catalina.start Server startup in 405 ms 验证tomcat 在浏览器中输入 loca…

一次性计时器

Name: 一次性计时器 Copyright:No Author: 袁神派蒙 Date: 22/05/24 20:40 Description: 一次性的计时器&#xff08;by 袁神派蒙&#xff09; 直接上代码&#xff1a; /*Name: 一次性计时器 Copyright:No Author: 袁神派蒙Date: 22/05/24 20:40Description: 一次性的计时器…

[算法] 优先算法(二): 双指针算法(下)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …