基于OkHttp封装一个简单易用的http工具

文章目录
  1. 基于OkHttp封装一个简单易用的http工具
    1. I. 封装后测试效果一览
    2. II. 封装实现
    3. III. 测试验证
    4. V. 其他
      1. 源码相关
      2. 声明
      3. 扫描关注,java分享

基于OkHttp封装一个简单易用的http工具

okHtt更常见的是用在android项目上实现http交互,而java后端,可能更多的使用httpclient;一般来讲,android的包,大部分也是可以用到java后端的,本片博文则主要是介绍如何使用okhttp实现http交互,并会做一个简单的封装,以达到更好的使用体验

本篇为纯工具封装,无原理分析

I. 封装后测试效果一览

基本上,最常见的http交互有两个,一个get请求,一个post请求,因此这里也就封装了这两种请求方式,并额外增加一个上传文件的功能,我们可以通过使用case,来看一下我们最终封装后的使用姿势

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
// 简单的get请求
@Test
public void testGet() {
String url = "https://zbang.online/wx/list";
try {
okhttp3.Response res = HttpWrapper.of(url).get();
if (res.isSuccessful()) {
String ans = res.body().string();
System.out.println("ans : " + ans);
}
} catch (IOException e) {
e.printStackTrace();
}
}

@Test
public void testUpload() {
String url = "https://zbang.online/wx/qrcode/encode";

String path = "/Users/yihui/Desktop/img/test.jpg";
File file = new File(path);

try {
Response res = HttpWrapper.of(url)
.file("image", file.getName(), "image/jpeg", file)
.addParam("content", "http://www.baidu.com")
.addParam("size", "400")
.upload();
if (res.isSuccessful()) {
String str = res.body().string();
System.out.println("ans: " + str);
}
} catch (IOException e) {
e.printStackTrace();
}
}

上面给出的是一个上传文件的case,实现主要是借助了builder模式,可以很简单的传递个中参数和配置,最后获取返回的结果,这样设计的好处很明显:

  • 使用简单
  • 阅读方便

II. 封装实现

接下来进入正题,如何封装这个工具类呢,一般而言,发起http请求,需要设置请求参数,设置请求头,所以builder内部的元素可以很清晰的定义了

首先是引入依赖

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

当然由于整个使用都比较简单,下面就直接贴出封装后的代码了

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
public class HttpWrapper {
private static OkHttpClient client = new OkHttpClient();

private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";

public static Builder of(String url) {
return new Builder(url);
}


public static class Builder {

private String url;

private Map<String, String> params;

private List<MultipartBody.Part> uploadParts;

Request.Builder reqBuilder;

Builder(String url) {
this.url = url;
params = new HashMap<>();
uploadParts = new ArrayList<>();

reqBuilder = new Request.Builder();


// 默认添加上user-agent
addHeader("User-Agent", DEFAULT_USER_AGENT);
}


// 添加参数
public Builder addParam(String key, String value) {
params.put(key, value);
return this;
}


// 添加头
public Builder addHeader(String key, String value) {
reqBuilder.addHeader(key, value);
return this;
}


public Builder file(String key, String fileName, String fileMime, byte[] bytes) {
MultipartBody.Part part = MultipartBody.Part.createFormData(
key,
fileName,
RequestBody.create(MediaType.parse(fileMime), bytes));
uploadParts.add(part);
return this;
}

public Builder file(String key, String fileName, String fileMime, File file) {
MultipartBody.Part part = MultipartBody.Part.createFormData(
key,
fileName,
RequestBody.create(MediaType.parse(fileMime), file));
uploadParts.add(part);
return this;
}

public Builder file(String key, String fileName, String fileMime, InputStream stream) throws IOException {
int size = stream.available();
byte[] bytes = new byte[size];
stream.read(bytes);
return file(key, fileName, fileMime, bytes);
}


/**
* 发送get请求
*
* @return
* @throws IOException
*/
public Response get() throws IOException {
StringBuilder urlBuilder = new StringBuilder(url);
if (!params.isEmpty()) {
urlBuilder.append("?").append(Joiner.on('&').withKeyValueSeparator('=').join(params));
}

return client.newCall(reqBuilder.url(urlBuilder.toString()).build()).execute();
}


/**
* post表单数据
*
* @return
*/
public Response post() throws IOException {
// 创建表单
FormBody.Builder formBodyBuilder = new FormBody.Builder();
if (!params.isEmpty()) {
params.forEach(formBodyBuilder::add);
}

return client.newCall(reqBuilder.url(url)
.post(formBodyBuilder.build())
.build())
.execute();
}


/**
* 文件上传
*
* @return
* @throws IOException
*/
public Response upload() throws IOException {
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
uploadParts.forEach(bodyBuilder::addPart);

// 添加参数
params.forEach(bodyBuilder::addFormDataPart);

return client.newCall(reqBuilder.url(url)
.post(bodyBuilder.build())
.build())
.execute();
}
}
}

针对上面的实现,有几个需要注意的地方

  • get请求时,将参数拼装到url上(需要考虑是否要编码?)
  • post请求时,主要借助 FormBody 来存储请求参数
  • 文件上传时,
    • 主要利用Part来封装上传的文件,借助 MultipartBody来包装Part和请求参数
    • 上传文件,需要指定其 MIME(即 Content-Type, 如 image/jpeg, audio/mp3, file/txt等)
    • 传文件的同时,也可以传递post参数,当然url参数也是可以的

III. 测试验证

前面给出的是一个传文件的case,下面则给出一个提交post表单的测试用例

这个http接口主要功能是实现markdown输出图片

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
@Test
public void testPost() {
String url = "https://zbang.online/wx/md2img";

String content = "h1 header\n" +
"============\n" +
"\n" +
"Paragraphs are separated by a blank line.\n" +
"\n" +
"2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists\n" +
"look like:\n" +
"\n" +
" * this one\n" +
" * that one\n" +
" * the other one";
String token = "0xdahdljk3u8eqhrjqwer90e";
String noborder = "true";


try {
Response res = HttpWrapper.of(url)
.addParam("content", content)
.addParam("token", token)
.addParam("noborder", noborder)
.addParam("type", "stream")
.post();
if (res.isSuccessful()) {
BufferedImage bf = ImageIO.read(res.body().byteStream());
System.out.println("over");
}
} catch (IOException e) {
e.printStackTrace();
}
}

测试演示

post表单

V. 其他

源码相关

源码可以参见: HttpWrapper.java

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见解不全,如有问题,欢迎批评指正

扫描关注,java分享

QrCode

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×