泪伤荡的编程指南 泪伤荡的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM篇
  • 新特性
  • 进阶篇
  • 网络
  • 操作系统
  • 数据结构与算法
  • 硬件
  • 基础篇
  • MySql
  • Oracle
  • PostgreSQL
  • 达梦
  • Redis
  • Mongodb
  • Hive
  • 数据库比较
  • Spring
  • SpringMvc
  • SpringBoot
  • Hibernate
  • iBatis
  • Mybatis
  • Mybatis-plus
  • Mybatis-plus-join
  • 各个框架对比
  • UML画图
  • 设计须知
  • 开发流程
  • 开发理论
  • 架构体系
  • 设计模式
  • 开源知识
  • 分布式解决方案
  • SpringCloud
  • API网关
  • 注册中心
  • 配置中心
  • 服务调用
  • 分布式事务
  • 消息队列
  • 调度作业
  • 链路追踪
  • 服务保障
  • 搜索引擎Elk
  • 安全框架
  • 监控体系
  • 部署容器
  • Netty
  • Tomcat
  • Nginx
  • 图片云存储
  • 云存储
  • 虚拟机Linux
  • 项目部署
  • 容器部署
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • Bug记录仓库
  • 随笔
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 视频网站
  • 音乐网站
  • 商城网站
  • 论坛网站
  • scrm项目
  • Yudao-cloud
  • RuoYi-Vu-cloud
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
  • Java术语
  • 命名英语
  • 业务英语
  • 表字段英语
  • 包名英语
Github (opens new window)
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM篇
  • 新特性
  • 进阶篇
  • 网络
  • 操作系统
  • 数据结构与算法
  • 硬件
  • 基础篇
  • MySql
  • Oracle
  • PostgreSQL
  • 达梦
  • Redis
  • Mongodb
  • Hive
  • 数据库比较
  • Spring
  • SpringMvc
  • SpringBoot
  • Hibernate
  • iBatis
  • Mybatis
  • Mybatis-plus
  • Mybatis-plus-join
  • 各个框架对比
  • UML画图
  • 设计须知
  • 开发流程
  • 开发理论
  • 架构体系
  • 设计模式
  • 开源知识
  • 分布式解决方案
  • SpringCloud
  • API网关
  • 注册中心
  • 配置中心
  • 服务调用
  • 分布式事务
  • 消息队列
  • 调度作业
  • 链路追踪
  • 服务保障
  • 搜索引擎Elk
  • 安全框架
  • 监控体系
  • 部署容器
  • Netty
  • Tomcat
  • Nginx
  • 图片云存储
  • 云存储
  • 虚拟机Linux
  • 项目部署
  • 容器部署
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • Bug记录仓库
  • 随笔
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 视频网站
  • 音乐网站
  • 商城网站
  • 论坛网站
  • scrm项目
  • Yudao-cloud
  • RuoYi-Vu-cloud
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
  • Java术语
  • 命名英语
  • 业务英语
  • 表字段英语
  • 包名英语
Github (opens new window)
  • 开发工具篇

    • idea设置

      • 配置篇
      • 快捷键篇
      • debug篇
      • 插件篇
    • 玩转Git

      • 基础知识梳理
      • Git配置相关操作
      • git修改已提交人的用户名和邮箱
      • git提交规范
      • 常见问题
    • Maven相关

      • Maven简介
      • Maven常用命令
      • 依赖管理
      • Maven生命周期与插件
      • Maven项目管理工具
    • Apifox使用小结
    • nvm使用小结
    • JMeter使用小记
  • 工具库篇

    • lombok工具库

      • lombok注解使用小结
      • Builder用法解析
      • 异常相关注解
    • EasyExcel小记

      • 工具类
      • 文件导入
      • 文件导出
    • 定时任务相关

      • 基础入门
      • SpringTask学习
      • Quartz学习
    • Hutool工具库

      • 图片压缩
    • 极光推送学习
    • OkHttp学习
      • 为什么选择 OkHttp?
      • 快速开始
        • 同步 GET 请求
        • 异步 GET 请求
        • POST 请求
        • 上传文件
        • 配置和拦截器
      • 工具类
      • 结论
      • 学习参考
    • BigDecimal类详解
    • PdfBox学习
  • 开发技巧篇

    • 常见数据校验注解
    • 字符串拼接的5种方式
    • 遍历集合的N种方式
    • 集合使用注意事项总结
    • MP使用小记
    • Stream流技巧总结
    • 字符串处理最佳实践
    • SQL语句优化
    • 时间字段处理小记
    • Curl用法解析
    • 列表分页的两种实现方案
    • HashMap根据value获取key
    • Map的7种遍历方式
    • 唯一索引和逻辑删除冲突解决方法
    • 正则表达式
    • 二维码扫码登录学习
    • 脱敏最佳实践
    • 日志记录相关
  • 工具类系列

    • 手写一个文件阅读器
    • 手写一个运行耗时计算器
    • 自定义实现Java Bean属性中列表元素格式校验注解及其实现
    • 父子工程项目搭建
    • 自制代码生成器
  • 随笔

    • HttpServletRequest知识小结
    • Spring MVC 项目构建流程
    • 虚拟机固定ip地址
    • 项目部署
    • 深入理解数组
    • IIS使用小记
    • From的两种类型解析
    • 开发疑惑
    • 开发小记
    • bug解决
  • 开发日常
  • 工具库篇
泪伤荡
2024-04-01
目录

OkHttp学习

# OkHttp 简介与使用示例

OkHttp 是一个高效的 HTTP 客户端,用于 Android、Java 应用程序以及 Kotlin 应用程序。它支持同步阻塞调用和异步调用,同时提供了强大的拦截器和重定向处理功能。OkHttp 由 Square 公司开发,因其高性能和易用性而广受欢迎。

# 为什么选择 OkHttp?

  • 性能:OkHttp 经过精心设计,以最小化网络延迟和数据使用量。
  • 简洁性:OkHttp 的 API 设计简洁直观,易于上手。
  • 可扩展性:OkHttp 支持自定义配置和拦截器,可以灵活地适应不同的需求。
  • 兼容性:OkHttp 支持 HTTP/2 和 WebSocket,适用于现代网络通信。

# 快速开始

首先,您需要在项目的 pom.xml 文件中添加 OkHttp 的依赖:

            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>4.12.0</version>
            </dependency>
1
2
3
4
5

# 同步 GET 请求

以下是一个简单的同步 GET 请求示例:

OkHttpClient client = new OkHttpClient();
String url = "https://api.example.com/data";

Request request = new Request.Builder()
        .url(url)
        .build();

try (Response response = client.newCall(request).execute()) {
    if (response.isSuccessful()) {
        String responseData = response.body().string();
        // 处理响应数据
    } else {
        // 处理错误响应
    }
} catch (IOException e) {
    // 处理网络异常
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 异步 GET 请求

对于不需要立即返回结果的场景,可以使用异步请求:

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 网络请求失败
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            String responseData = response.body().string();
            // 异步处理响应数据
        } else {
            // 异步处理错误响应
        }
    }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# POST 请求

发送 POST 请求并附带请求体:

String url = "https://api.example.com/submit";
String json = "{\"name\":\"John\",\"age\":30}";

RequestBody body = RequestBody.create(json, MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
        .url(url)
        .post(body)
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 网络请求失败
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            // 请求成功
        } else {
            // 处理错误响应
        }
    }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 上传文件

OkHttp 也支持文件上传:

String url = "https://api.example.com/upload";
File file = new File("/sdcard/image.png");

RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("file", file.getName(), fileBody)
        .build();

Request request = new Request.Builder()
        .url(url)
        .post(requestBody)
        .build();

client.newCall(request).enqueue(new Callback() {
    // ...
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 配置和拦截器

OkHttp 允许您配置连接参数和添加拦截器:

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .addInterceptor(new LoggingInterceptor())
        .build();
1
2
3
4
5
6

# 工具类

/**
 * @author chenmeng
 */
@SuppressWarnings("all")
public class OkHttpUtil {

    private static final Logger logger = LoggerFactory.getLogger("okHttpReq");

    private static final long DEFAULT_TIMEOUT = 5000;
    private static final int MAX_IDLE_CONNECTION = 5;
    private static final long KEEP_ALIVE_DURATION = 1;
    public static final String JSON_CONTENT_TYPE = "application/json; charset=utf-8";
    public static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";

    private OkHttpUtil() {
        // 单例模式,防止外部实例化
    }

    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .callTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            .connectionPool(new ConnectionPool(MAX_IDLE_CONNECTION, KEEP_ALIVE_DURATION, TimeUnit.MINUTES))
            .build();

    /**
     * 发送GET请求
     *
     * @param url 请求URL
     * @return 响应结果字符串
     */
    public static String sendGet(String url) {
        return sendGetWithHeaders(url, null, null);
    }

    /**
     * 携带参数发送GET请求
     *
     * @param url   请求URL
     * @param param 请求参数
     * @return 响应结果字符串
     */
    public static String sendGetWithParam(String url, String param) {
        return sendGetWithHeaders(url, param, null);
    }

    /**
     * 携带请求头发送GET请求
     *
     * @param url     请求URL
     * @param param   请求参数
     * @param headers 请求头(可选)
     * @return 响应结果字符串
     */
    public static String sendGetWithHeaders(String url, String param, Map<String, String> headers) {
        String realUrl = url;
        if (StrUtil.isNotBlank(param)) {
            realUrl = url + "?" + param;
        }
        Request.Builder builder = new Request.Builder()
                .url(realUrl)
                .header("accept", "*/*")
                .header("connection", "Keep-Alive")
                .get();
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();

        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            if (response.isSuccessful()) {
                // 处理响应数据
                long time = response.receivedResponseAtMillis() - response.sentRequestAtMillis();
                String result = response.body() != null ? response.body().string() : null;
                printRequestLog(url, null, param, time, result);
                return result;
            } else {
                // 处理错误响应
                // return response.toString();
                throw new IOException(String.valueOf(response));
            }
        } catch (Exception e) {
            // 处理网络异常
            logger.error("invoke Remote 【GET】 Method exception!== url【{}】,param【{}】", url, param);
            return returnErrorResult("远程请求失败:" + e.getMessage()).toString();
        }
    }

    /**
     * 发送POST请求(application/json; charset=utf-8)
     *
     * @param url   请求URL
     * @param param JSON字符串请求体
     * @return 响应结果字符串
     */
    public static String sendPostJson(String url, String param) {
        return sendPostJsonWithHeaders(url, param, null);
    }

    /**
     * 携带请求头发送POST请求(application/json)
     *
     * @param url     请求URL
     * @param param   JSON字符串请求体
     * @param headers 请求头(可选)
     * @return 响应结果字符串
     */
    public static String sendPostJsonWithHeaders(String url, String param, Map<String, String> headers) {
        MediaType mediaType = MediaType.parse(JSON_CONTENT_TYPE);
        RequestBody requestBody = RequestBody.create(param, mediaType);

        Request.Builder builder = new Request.Builder()
                .url(url)
                .header("accept", "*/*")
                .header("connection", "Keep-Alive")
                .header("Content-Type", JSON_CONTENT_TYPE)
                .post(requestBody);

        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();

        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            if (response.isSuccessful()) {
                // 处理响应数据
                long time = response.receivedResponseAtMillis() - response.sentRequestAtMillis();
                String result = response.body() != null ? response.body().string() : null;
                printRequestLog(url, JSON_CONTENT_TYPE, param, time, result);
                return result;
            } else {
                // 处理错误响应
                throw new IOException(String.valueOf(response));
            }
        } catch (Exception e) {
            // 处理网络异常
            logger.error("invoke Remote 【POST】 Method exception!== url【{}】,param【{}】", url, param, e);
            return returnErrorResult("Remote Request Fail--" + e.getMessage()).toString();
        }
    }

    /**
     * 发送POST请求(application/x-www-form-urlencoded)
     *
     * @param url    请求URL
     * @param params 请求参数(可选)
     * @return 响应结果字符串
     */
    public static String sendPostForm(String url, Map<String, Object> params) {
        return sendPostFormWithHeaders(url, params, null);
    }

    /**
     * 携带请求头发送POST请求(application/x-www-form-urlencoded)
     *
     * @param url     请求URL
     * @param params  请求参数(可选)
     * @param headers 请求头(可选)
     * @return 响应结果字符串
     */
    public static String sendPostFormWithHeaders(String url, Map<String, Object> params,
                                                 Map<String, String> headers) {
        RequestBody formBody;
        StringBuilder strParamsBuilder = new StringBuilder();
        if (params != null && !params.isEmpty()) {
            FormBody.Builder formBuilder = new FormBody.Builder();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                formBuilder.add(entry.getKey(), entry.getValue().toString());
            }
            formBody = formBuilder.build();
            // 打印参数
            for (Map.Entry<String, Object> e : params.entrySet()) {
                strParamsBuilder.append(e.getKey()).append("=").append(e.getValue()).append("&");
            }
        } else {
            // 若无参数,创建一个空的FormBody
            formBody = new FormBody.Builder().build();
        }
        String strParams = strParamsBuilder.toString();

        Request.Builder builder = new Request.Builder()
                .url(url)
                .header("accept", "*/*")
                .header("connection", "Keep-Alive")
                .header("Content-Type", FORM_CONTENT_TYPE)
                .post(formBody);

        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();

        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            if (response.isSuccessful()) {
                // 处理响应数据
                long time = response.receivedResponseAtMillis() - response.sentRequestAtMillis();
                String result = response.body() != null ? response.body().string() : null;
                printRequestLog(url, FORM_CONTENT_TYPE, strParams, time, result);
                return result;
            } else {
                // 处理错误响应
                throw new IOException(String.valueOf(response));
            }
        } catch (Exception e) {
            // 处理网络异常
            logger.error("invoke Remote 【POST】 Method exception!== url【{}】,param【{}】", url, strParams);
            return returnErrorResult("Remote Request Fail :" + e.getMessage()).toString();
        }
    }

    public static void printRequestLog(
            String url, String contentType, String data, Long time, String result) {
        // if (StrUtil.isNotBlank(result) && result.length() > 200) {
        //     result = result.substring(0, 200) + "...";
        // }
        String log =
                "\n================== Remote Request info ==================\n"
                        + String.format("Request URL: %s \n", url)
                        + String.format("Request Content-Type: %s\n", contentType)
                        + String.format("Request Parameter: %s \n", data)
                        + String.format("Request Time: %s ms \n", time)
                        + String.format("Response Result: %s \n", result)
                        + "================== Remote Request info ==================\n";
        logger.info(log);
    }

    public static JSONObject returnErrorResult(String msg) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("code", 1);
        jsonObject.putOpt("msg", msg);
        jsonObject.putOpt("data", null);
        return jsonObject;
    }
}
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

# 结论

OkHttp 是一个功能强大且易于使用的 HTTP 客户端,它提供了丰富的功能来满足各种网络请求的需求。无论是简单的 GET 请求还是复杂的文件上传,OkHttp 都能够提供高效的解决方案。通过上述示例,您可以快速地在自己的应用程序中使用 OkHttp 进行网络通信。

# 学习参考

  • 官方文档 (opens new window)
  • 七大主流的HttpClient程序比较 - 知乎 (zhihu.com) (opens new window)
  • Okhttp3基本使用 - 简书 (jianshu.com) (opens new window)
上次更新: 2024/10/26 02:01:17
极光推送学习
BigDecimal类详解

← 极光推送学习 BigDecimal类详解→

Theme by Vdoing | Copyright © 2024-2025 泪伤荡 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式