起步
安装
Maven
单独使用 OkHttps
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps</artifactId>
<version>3.5.3</version>
</dependency>
2
3
4
5
单独使用 OkHttps 需要自定义MsgConvertor
,否则无法使用 自动正反序列化 相关功能,后文会详细讲解哪些功能会受到此影响。
与 fastjson 一起使用
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps-fastjson</artifactId>
<version>3.5.3</version>
</dependency>
2
3
4
5
与 gson 一起使用
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps-gson</artifactId>
<version>3.5.3</version>
</dependency>
2
3
4
5
与 jackson 一起使用
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps-jackson</artifactId>
<version>3.5.3</version>
</dependency>
2
3
4
5
TIP
以上依赖四选一即可
集成 XML 扩展(since v2.4.2)
<!-- 若使用的是 Oracle JDK 8, 则一个依赖即可 -->
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps-xml</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 若使用的是 Oracle JDK 9+ 或 OpenJDK 则还需要添加一个依赖 -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
使用 Stomp 客户端
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>okhttps-stomp</artifactId>
<version>3.5.3</version>
</dependency>
2
3
4
5
Gradle
单独使用 OkHttps
implementation 'com.ejlchina:okhttps:3.5.3'
单独使用 OkHttps 需要自定义MsgConvertor
,否则无法使用 自动正反序列化 相关功能,后文会详细讲解哪些功能会受到此影响。
与 fastjson 一起使用
implementation 'com.ejlchina:okhttps-fastjson:3.5.3'
与 gson 一起使用
implementation 'com.ejlchina:okhttps-gson:3.5.3'
与 jackson 一起使用
implementation 'com.ejlchina:okhttps-jackson:3.5.3'
TIP
以上依赖四选一即可
集成 XML 扩展(since v2.4.2)
// 若使用的是 Oracle JDK 8, 则一个依赖即可
implementation 'com.ejlchina:okhttps-xml:3.5.3'
// 若使用的是 Oracle JDK 9+ 或 OpenJDK 则还需要添加一个依赖
implementation 'com.sun.xml.bind:jaxb-impl:2.3.3'
2
3
4
使用 Stomp 客户端
implementation 'com.ejlchina:okhttps-stomp:3.5.3'
JDK 版本
安卓中使用需要把 JDK 版本调成 1.8,在 app 模块的 build.gradle 中加入以下配置即可:
android {
// 省略其它配置..
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
2
3
4
5
6
7
使用
构建 HTTP
HTTP http = HTTP.builder().build();
以上代码构建了一个最简单的HTTP
实例,它拥有以下方法:
sync(String url)
开始一个同步 HTTP 请求async(String url)
开始一个异步 HTTP 请求webSocket(String url)
开始一个 WebSocket 连接cancel(String tag)
按标签取消(同步 | 异步 | WebSocket)连接cancelAll()
取消所有(同步 | 异步 | WebSocket)连接request(Request request)
OkHttp 原生 HTTP 请求webSocket(Request request, WebSocketListener listener)
OkHttp 原生 WebSocket 连接newBuilder()
用于重新构建一个 HTTP 实例
为了使用方便,在构建的时候,我们更愿意指定一个BaseUrl
和MsgConvertor
(详见 设置 BaseUrl 和 消息转换器):
HTTP http = HTTP.builder()
.baseUrl("http://api.example.com")
.addMsgConvertor(new GsonMsgConvertor())
.build();
2
3
4
上例中的GsonMsgConvertor
来自okhttps-gson
。为了简化文档,下文中出现的http
均是在构建时设置了BaseUrl
和MsgConvertor
的HTTP
实例。
同步请求
使用方法sync(String url)
开始一个同步请求:
List<User> users = http.sync("/users") // http://api.example.com/users
.get() // GET请求
.getBody() // 获取响应报文体
.toList(User.class); // 得到目标数据
2
3
4
方法sync
返回一个同步HttpTask
,可链式使用。
异步请求
使用方法async(String url)
开始一个异步请求:
http.async("/users/1") // http://api.example.com/users/1
.setOnResponse((HttpResult res) -> {
// 得到目标数据
User user = res.getBody().toBean(User.class);
})
.get(); // GET请求
2
3
4
5
6
方法async
返回一个异步HttpTask
,可链式使用。
WebSocket
使用方法webSocket(String url)
开始一个 WebSocket 通讯:
http.webSocket("/chat")
.setOnOpen((WebSocket ws, HttpResult res) -> {
ws.send("向服务器问好");
})
.setOnMessage((WebSocket ws,Message msg) -> {
// 从服务器接收消息(自动反序列化)
Chat chat = msg.toBean(Chat.class);
// 相同的消息发送给服务器(自动序列化 Chat 对象)
ws.send(chat);
})
.listen(); // 启动监听
2
3
4
5
6
7
8
9
10
11
方法webSocket
返回一个支持 WebSocket 的HttpTask
,也可链式使用。
请求三步曲
第一步、确定请求方式
同步 HTTP(sync
)、异步 HTTP(async
)或 WebSocket(webSocket
)
第二步、构建请求任务
addXxxPara
- 添加请求参数setOnXxxx
- 设置回调函数tag
- 添加标签- ...
第三步、调用请求方法
HTTP 请求方法:
get()
- GET 请求post()
- POST 请求put()
- PUT 请求delete()
- DELETE 请求- ...
Websocket 方法:
listen()
- 启动监听
任意请求,都遵循请求三部曲!
IDEA 小技巧
由于 OkHttps 遵循请求三部曲,所以我们在 IDEA 中设置一个代码模板(Android Studio 一样设置)
- 菜单 File -> Settings 打开 Settings 设置框
- 展开 Editor -> Live Templates
如图设置好后,写代码时,输入oks
,按回车键,就会自动生成模版,赶快尝试一下吧。
工具类
OkHttps 提供了两个开箱即用的工具类,让你从此告别封装工具类的烦恼:
OkHttps | HttpUtils
工具类 | 起始版本 | 功能特点 |
---|---|---|
OkHttps | 2.0.0.RC | 支持自动注入MsgConvertor ,支持 SPI 方式注入配置,推荐用于主应用中的网络开发 |
HttpUtils | 1.0.0 | 自2.0.0.RC 开始支持自动注入MsgConvertor ,不建议再做其它配置,推荐用于第三方依赖包中的网络开发 |
这两个工具都类会自动以 SPI 方式注入依赖中的MsgConvertor
(在第一次使用的时候),只要你的项目中添加了相关依赖(如:okhttps-fastjson 等)。并且它们和HTTP
接口拥有几乎一样的方法,并且这些方法都是静态的:
sync(String url)
开始一个同步 HTTP 请求async(String url)
开始一个异步 HTTP 请求webSocket(String url)
开始一个 WebSocket 连接cancel(String tag)
按标签取消(同步 | 异步 | WebSocket)连接cancelAll()
取消所有(同步 | 异步 | WebSocket)连接request(Request request)
OkHttp 原生 HTTP 请求webSocket(Request request, WebSocketListener listener)
OkHttp 原生 WebSocket 连接
例如,使用OkHttps
,无需考虑构造HTTP
实例,你可以这样发起一个请求:
OkHttps.async("https://api.example.com/auth/login")
.addBodyPara("username", "jack")
.addBodyPara("password", "xxxx")
.setOnResponse((HttpResult result) -> {
// 得到返回数据,使用 Mapper 可省去定义一个实体类
Mapper mapper = result.getBody().toMapper();
// 登录是否成功
boolean success = mapper.getBool("success");
})
.post();
2
3
4
5
6
7
8
9
10
向 OkHttps
注入配置
工具类OkHttps
还支持以 SPI 方式注入自定义配置,分以下两步:
第一步、新建一个配置类,实现com.ejlchina.okhttps.Config
接口
例如:
package com.example.okhttps;
import com.ejlchina.okhttps.Config;
import com.ejlchina.okhttps.HTTP;
public class OkHttpsConfig implements Config {
@Override
public void with(HTTP.Builder builder) {
// 在这里对 HTTP.Builder 做一些自定义的配置
builder.baseUrl("https://api.domo.com");
// 如果项目中添加了 okhttps-fastjson 或 okhttps-gson 或 okhttps-jackson 依赖
// OkHttps 会自动注入它们提供的 MsgConvertor
// 所以这里就不需要再配置 MsgConvertor 了 (内部实现自动注入的原理也是 SPI)
// 但如果没有添加这些依赖,那还需要自定义一个 MsgConvertor
builder.addMsgConvertor(new MyMsgConvertor());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
以上做简单的演示,更多配置案例可参考 安卓-最佳实践 章节。
第二步、在项目的/src/main
目录下新建resources/META-INF/services/com.ejlchina.okhttps.Config
文件,文件内容是上一步自定义的配置类的全名
例如:
如果你使用的是 JDK9+ 且 启用了模块功能,则还需要在你的 module-info.java
文件里配置一行代码:
provides com.ejlchina.okhttps.Config with com.example.okhttps.OkHttpsConfig;
以上两步就完成了对OkHttps
工具类的自定义配置,接下来你便可以体验它神奇的能力了:
List<User> users = OkHttps.sync("/users") // http://api.example.com/users
.get().getBody().toList(User.class);
2
注意
需要特别注意的是:META-INF
与 services
是父子两级目录,而不是一个目录!! 虽然在 IDEA 中会简显成 META-INF.services
形式,但我猜聪明的你肯定不会被它误导的 ^_^。
为什么要这样呢?
有同学可能会疑问,为什么要这样配置呢,不能直接给OkHttps
设置一个HTTP
实例吗,像这样:
HTTP http = HTTP.builder()
// 自定义配置...
.build();
OkHttps.set(http);
2
3
4
5
这样做在一般情况下确实可以,但是在某些 Java 虚拟机上(特别在 Android)中,有一个致命的缺陷:那就是系统在某些情况下会回收静态变量,而OkHttps
内部持有的HTTP
实例一旦被回收后,上述方式自定义的配置就会丢失,这样在后续的逻辑处理中就可能会造成严重的问题!
而 SPI 注入的方式则可以很好的解决这个问题:即使OkHttps
内部的HTTP
实例被回收,在下次使用时,OkHttps
又会自动加载注入的配置重新构建一个HTTP
实例,这样就保证了用户自定义的配置不会丢失。
所以我们推荐在 Android 应用开发中,直接使用OkHttps
,自定义配置通过 SPI 方式注入。
而在开发具有网络请求需求的依赖项目时,直接使用HttpUtils
并且不做自定义的配置,如果一定要自定义配置,那就使用HTTP.Builder
重新构建一个HTTP
实例使用吧。
访问项目配置文件
OkHttps 的配置类如何方法项目配置文件呢?这里介绍两种方法。
方法一
如果你有一个配置文件的读取工具,当然可以直接读取配置。
方法二
如果你用的是 Spring 框架,则可以先在 Spring 的 Bean 里加载配置,然后将这个 Bean 单例化,提供静态访问方法,然后再 配置类 里去获取那个 Bean,例如:
@Component
public class ConfigBean {
@Value("${okhttps.baseUrl}") // 加载配置
private String baseUrl;
private static ConfigBean instance;
public ConfigBean() {
instance = this; // 将该 Bean 单例化
}
public static ConfigBean getInstance() {
return instance; // 提供静态访问方法
}
// 省略 Getter Seatter
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
然后再 OkHttps 的配置类里就可以使用这个配置了:
public class OkHttpsConfig implements Config {
@Override
public void with(HTTP.Builder builder) {
// 获取 ConfigBean
ConfigBean confg = ConfigBean.getInstance();
// 使用配置
builder.baseUrl(confg.getBaseUrl());
// 省略其它配置
}
}
2
3
4
5
6
7
8
9
10
11
12
至此,你已轻松学会了 OkHttps 90% 的常规用法!但别急,还有非常关键的内容在后面,一定要看完哦,后面更精彩。