Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于
所有文章 工具

Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于

OkHttp的使用与跳坑示例

阅读数:次 2020-03-22
字数统计: 1.2k字   |   阅读时长≈ 6分

mark

OkHttp是一个优秀的网络请求框架,我开始接触Android开发的时候就用过这个网络请求框架,官方的参考文档在这里 https://square.github.io/okhttp/ ,本文演示了使用OkHttp框架进行简单的Get、Post(表单形式和JSON形式)、Delete、附加请求头、请求异步回调,文件的上传和下载等常用操作。最后记录了一个今天调试了很久的坑,那就是response.body().string()只能有效调用一次,注意Debug的时候对结果造成的改变!JDK9的HttpURLConnection有很多变化,下次博客中会有演示和说明。

首选引入这个依赖就可以使用OkHTTP了

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>

<!-- 这个是我演示Post请求JSON格式的时候用到的 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>

如果是 gradle 管理的项目,则只需要引入:

1
compile 'com.squareup.okhttp3:okhttp:3.6.0'

1、Get请求示例

1
2
3
4
5
6
7
8
9
String url = "http://zouchanglin.cn";
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().get().url(url).build();
try {
Response execute = okHttpClient.newCall(request).execute();
System.out.println(execute.body().string());
} catch (IOException e) {
e.printStackTrace();
}

2、Post请求示例

1、JSON请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
String url = "http://zouchanglin.cn/info/create";
OkHttpClient okHttpClient = new OkHttpClient();
Map<String, Object> map = new HashMap<>();
map.put("name", "Mike");
map.put("age", "20");
RequestBody requestBody = RequestBody.create(
MediaType.parse("application/json; charset=utf-8"),
JSONObject.toJSONString(map));
Request request = new Request.Builder().post(requestBody).url(url).build();
try {
Response response = okHttpClient.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

2、表单数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
String url = "http://zouchanglin.cn/info/create";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("name", "Mike")
.add("age", "20").build();
Request request = new Request.Builder().post(requestBody).url(url).build();
try {
Response response = okHttpClient.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

3、Delete请求示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
String url = "http://zouchanglin.cn/info/remove";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("id", "001002003004").build();
Request request = new Request.Builder()
.delete(requestBody).url(url).build();
try {
Response response = okHttpClient.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

4、附加请求头示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
String url = "http://zouchanglin.cn/info/remove";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("id", "001002003004").build();
Request request = new Request.Builder()
.delete(requestBody)
.addHeader("Accept", "application/vnd..")
.url(url).build();
try {
Response response = okHttpClient.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

5、请求异步回调示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
String url = "http://zouchanglin.cn/info/remove";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("id", "0010003004").build();
Request request = new Request.Builder().delete(requestBody).url(url).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//TODO...
}

@Override
public void onResponse(Call call, Response response) throws IOException {
//TODO...
}
});
}

6、上传文件加参数示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@PostMapping("upload")
public String uploadToRemoteHost(String ip, String path, String fileId) {
String url = String.format("http://%s:8080//api/host/file/create/", ip);
//找到文件对象
Optional<ImageFile> bigFileById = fileService.getBigFileById(fileId);
if(bigFileById.isPresent()){
ImageFile imageFile = bigFileById.get();
OkHttpClient okHttpClient = new OkHttpClient();
MultipartBody.Builder requestBody = new MultipartBody.Builder();
requestBody.setType(MultipartBody.FORM);
RequestBody body = RequestBody.create(
MediaType.parse("application/octet-stream"),
imageFile.getContent().getData());

// 参数分别为 请求key 文件名称 RequestBody
requestBody.addFormDataPart("file", imageFile.getName(), body);
//要上传的文字参数
Map<String, String> map = new HashMap<>();
map.put("name", imageFile.getName());
map.put("path", path);
for (String key : map.keySet()) {
requestBody.addFormDataPart(key, map.get(key));
}
MultipartBody build = requestBody.build();
try {
Request request = new Request.Builder().post(build).url(url).build();
Response execute = okHttpClient.newCall(request).execute();
if(execute.isSuccessful()){
return execute.body().string();
}
return JSONObject.toJSONString(ResultVOUtil.error(1, "网络错误"));
} catch (IOException e) {
e.printStackTrace();
return JSONObject.toJSONString(ResultVOUtil.error(2, "网络错误2"));
}
}
return JSONObject.toJSONString(ResultVOUtil.error(3, "文件不存在"));
}

7、下载文件示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public void downloadImg(View view){
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder().get()
.url("http://wwwx.yyy/a.png")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("moer", "onFailure: ");;
}

@Override
public void onResponse(Call call, Response response) throws IOException {
//拿到字节流
InputStream is = response.body().byteStream();

int len = 0;
File file = new File(Environment.getExternalStorageDirectory(), "n.png");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[128];

while ((len = is.read(buf)) != -1){
fos.write(buf, 0, len);
}

fos.flush();
//关闭流
fos.close();
is.close();
}
});
}

8、OkHttp的坑

OkHttp请求回调中response.body().string()只能有效调用一次,调用response.body().string()的时候数据流已经关闭了,再次调用就是提示已经closed,抛出java.lang.IllegalStateException: closed异常,所以这个坑还是有点大,我在debug的时候由于已经监视了一次response.body().string()的返回值,在代码中跑完就是IllegalStateException。 调试代码调试时,表达式的监视有时候会影响代码的运行,比如就像OkHttp这种情况。

赏

谢谢你请我喝咖啡

支付宝
微信
  • 本文作者: Tim
  • 本文链接: https://zouchanglin.cn/878430602.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!
  • JavaWeb
  • 上传下载
  • 异步
  • Web开发

扫一扫,分享到微信

线程相关的基础问题
Docker私服配置HTTPS
  1. 1. 1、Get请求示例
  2. 2. 2、Post请求示例
  3. 3. 3、Delete请求示例
  4. 4. 4、附加请求头示例
  5. 5. 5、请求异步回调示例
  6. 6. 6、上传文件加参数示例
  7. 7. 7、下载文件示例
  8. 8. 8、OkHttp的坑
© 2017-2021 Tim
本站总访问量次 | 本站访客数人
  • 所有文章
  • 工具

tag:

  • 生活
  • Android
  • 索引
  • MySQL
  • 组件通信
  • Nginx
  • JavaSE
  • JUC
  • JavaWeb
  • 模板引擎
  • 前端
  • Linux
  • 计算机网络
  • Docker
  • C/C++
  • JVM
  • 上传下载
  • JavaEE
  • SpringCloud
  • Golang
  • Gradle
  • 网络安全
  • 非对称加密
  • IDEA
  • SpringBoot
  • Jenkins
  • 字符串
  • vim
  • 存储
  • 文件下载
  • Mac
  • Windows
  • NIO
  • RPC
  • 集群
  • 微服务
  • SSH
  • 配置中心
  • XML
  • Chrome
  • 压力测试
  • Git
  • 博客
  • 概率论
  • 排序算法
  • 分布式
  • 异常处理
  • 文件系统
  • 哈希
  • openCV
  • 栈
  • 回溯
  • SpringCore
  • 流媒体
  • rtmp
  • 面向对象
  • Vue
  • ElementUI
  • 软件工程
  • 异步
  • 自定义UI
  • ORM框架
  • 模块化
  • 交互式
  • Jsoup
  • Http Client
  • LRUCache
  • RabbitMQ
  • 消息通信
  • 服务解耦
  • 负载均衡
  • 权限
  • 多线程
  • 单例模式
  • Protobuf
  • 序列化
  • Python
  • m3u8
  • 堆
  • 二叉树
  • 自定义View
  • 观察者模式
  • 设计模式
  • 线程池
  • 动态扩容
  • 高可用
  • GC
  • ffmpeg
  • SpringMVC
  • REST
  • Redis
  • 缓存中间件
  • UML
  • Maven
  • Netty
  • 高性能网络
  • IPC通信
  • IO
  • Stream
  • 发布订阅
  • SQLite
  • Hash
  • 集合框架
  • 链表
  • Lambda
  • 汇编语言
  • 组件化
  • Router
  • 开发工具

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 思维导图
  • PDF工具
  • 无损放大
  • 代码转图
  • HTTPS证书