起步

安装

Maven

单独使用 OkHttps

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

单独使用 OkHttps 需要自定义MsgConvertor,否则无法使用 自动正反序列化 相关功能,后文会详细讲解哪些功能会受到此影响。

与 fastjson 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-fastjson</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 fastjson2 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-fastjson2</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 fastjson2-jsonb 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-fastjson2-jsonb</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 gson 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-gson</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 jackson 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-jackson</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 jackson-xml 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-jackson-xml</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 jackson-yaml 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-jackson-yaml</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

与 snack3 一起使用

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-snack3</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

TIP

以上依赖九选一即可

使用 Stomp 客户端

<dependency>
     <groupId>cn.zhxu</groupId>
     <artifactId>okhttps-stomp</artifactId>
     <version>4.0.0</version>
</dependency>
1
2
3
4
5

Gradle

单独使用 OkHttps

implementation 'cn.zhxu:okhttps:4.0.0'
1

单独使用 OkHttps 需要自定义MsgConvertor,否则无法使用 自动正反序列化 相关功能,后文会详细讲解哪些功能会受到此影响。

与 fastjson 一起使用

implementation 'cn.zhxu:okhttps-fastjson:4.0.0'
1

与 fastjson2 一起使用

implementation 'cn.zhxu:okhttps-fastjson2:4.0.0'
1

与 fastjson2-jsonb 一起使用

implementation 'cn.zhxu:okhttps-fastjson2-jsonb:4.0.0'
1

与 gson 一起使用

implementation 'cn.zhxu:okhttps-gson:4.0.0'
1

与 jackson 一起使用

implementation 'cn.zhxu:okhttps-jackson:4.0.0'
1

与 jackson-xml 一起使用

implementation 'cn.zhxu:okhttps-jackson-xml:4.0.0'
1

与 jackson-yaml 一起使用

implementation 'cn.zhxu:okhttps-jackson-yaml:4.0.0'
1

与 snack3 一起使用

implementation 'cn.zhxu:okhttps-snack3:4.0.0'
1

TIP

以上依赖九选一即可

使用 Stomp 客户端

implementation 'cn.zhxu:okhttps-stomp:4.0.0'
1

JDK 版本

安卓中使用需要把 JDK 版本调成 1.8,在 app 模块的 build.gradle 中加入以下配置即可:

android {
    // 省略其它配置..
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
}
1
2
3
4
5
6
7

使用

构建 HTTP

HTTP http = HTTP.builder().build();
1

以上代码构建了一个最简单的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 实例

为了使用方便,在构建的时候,我们更愿意指定一个BaseUrlMsgConvertor(详见 设置 BaseUrl消息转换器):

HTTP http = HTTP.builder()
        .baseUrl("http://api.example.com")
        .addMsgConvertor(new GsonMsgConvertor())
        .build();
1
2
3
4

上例中的GsonMsgConvertor来自okhttps-gson。为了简化文档,下文中出现的http均是在构建时设置了BaseUrlMsgConvertorHTTP实例。

同步请求

使用方法sync(String url)开始一个同步请求:

List<User> users = http.sync("/users") // http://api.example.com/users
        .get()                         // GET请求
        .getBody()                     // 获取响应报文体
        .toList(User.class);           // 得到目标数据
1
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请求
1
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();                     // 启动监听
1
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

工具类起始版本功能特点
OkHttps2.0.0.RC支持自动注入MsgConvertor,支持 SPI 方式注入配置,推荐用于主应用中的网络开发
HttpUtils1.0.02.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();
1
2
3
4
5
6
7
8
9
10

OkHttps 注入配置

工具类OkHttps还支持以 SPI 方式注入自定义配置,分以下两步:

第一步、新建一个配置类,实现cn.zhxu.okhttps.Config接口

例如:

package com.example.okhttps;

import cn.zhxu.okhttps.Config;
import cn.zhxu.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());
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

以上做简单的演示,更多配置案例可参考 安卓-最佳实践 章节。

第二步、在项目的/src/main目录下新建resources/META-INF/services/cn.zhxu.okhttps.Config文件,文件内容是上一步自定义的配置类的全名

例如:

如果你使用的是 JDK9+启用了模块功能,则还需要在你的 module-info.java 文件里配置一行代码:

provides cn.zhxu.okhttps.Config with com.example.okhttps.OkHttpsConfig;
1

以上两步就完成了对OkHttps工具类的自定义配置,接下来你便可以体验它神奇的能力了:

List<User> users = OkHttps.sync("/users") // http://api.example.com/users
        .get().getBody().toList(User.class);
1
2

注意

需要特别注意的是:META-INFservices 是父子两级目录,而不是一个目录!! 虽然在 IDEA 中会简显成 META-INF.services 形式,但我猜聪明的你肯定不会被它误导的 ^_^。

为什么要这样呢?

有同学可能会疑问,为什么要这样配置呢,不能直接给OkHttps设置一个HTTP实例吗,像这样:

HTTP http = HTTP.builder()
        // 自定义配置...
        .build();

OkHttps.set(http);
1
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
}
1
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());
        // 省略其它配置
    }

}
1
2
3
4
5
6
7
8
9
10
11
12

至此,你已轻松学会了 OkHttps 90% 的常规用法!但别急,还有非常关键的内容在后面,一定要看完哦,后面更精彩。