Http客户端OkHttp的基本使用
okhttp是一款优秀的http客户端,支持异步,http2等等。
Github & Maven
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.0</version>
</dependency>
基本的组件
OkHttpClient
它类似于一个浏览器,在应用中应该全局唯一
Request
它表示一次Http请求,可以设置url地址,请求头等信息
RequestBody
它表示http请求体
Response
它表示一次Http响应,可以获取到响应体,响应头等信息
ResponseBody
它表示Http响应体
基本的流程
- 创建OkHttpClient客户端
- 创建请求体对象
- 创建请求对象,设置URL,Header信息
- 使用客户端对象执行请求,获取到Response对象
- 从Response对象获取到响应体
- 释放资源
GET 请求
基本的请求
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost:8081/")
.addHeader("foo","bar") // http消息头
.build();
Response response = okHttpClient.newCall(request).execute();
response.headers(); //响应头
ResponseBody responseBody = response.body();
responseBody.string(); // 响应体
文件下载
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://localhost:8081/down/demo.mp4").build();
Response response = client.newCall(request).execute();
// 从响应获取到InputStream
InputStream inputStream = response.body().byteStream();
POST请求
application/x-www-form-urlencoded
OkHttpClient client = new OkHttpClient();
// 表单请求体
RequestBody body = new FormBody.Builder()
.add("name","KevinBlandy") // 添加表单项
.addEncoded("charset","utf-8") // 添加表单项,使用URI编码
.build();
Request request = new Request.Builder()
.url("http://localhost:8081/user")
.post(body).build();
Response response = client.newCall(request).execute();
response.body().string();
application/json
// 创建Content-Type头为JSON
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
JSONObject requestBody = new JSONObject();
requestBody.put("name","SpringBoot中文社区");
// 根据ContentType构建请求体
RequestBody body = RequestBody.create(mediaType, requestBody.toJSONString());
Request request = new Request.Builder()
.url("http://localhost:8081/name")
.post(body) // 设置请求体
.build();
Response response = client.newCall(request).execute();
response.body().string();
multipart/form-data
OkHttpClient client = new OkHttpClient();
// 需要上传的目标文件
File file = new File("D:\\demo.mp4");
// 创建Multipart表单体
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM) //设置ContentType为:multipart/form-data
// 添加一个文件part,
// part名称,文件名称,通过RequestBody构建请求体(文件的类型,目标文件)
.addFormDataPart("file",file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
//RequestBody有N多重载方法,不仅仅可以基于本地磁盘构建表单项,还可以基于字节数据构建
// .addFormDataPart("file",file.getName(), RequestBody.create(MediaType.parse("image/png"), new byte[]{}))
// 添加一个普通的form-urlencoded part
.addFormDataPart("name", "KevinBlandy")
.build();
Request request = new Request.Builder()
.url("http://localhost:8081/upload")
.post(requestBody).build();
Response response = client.newCall(request).execute();
response.body().string();
其他的请求
基本上就是大同小异了,你可以通过阅读源码去进一步的了解
异步请求
可以通过回调的方式去处理服务端的响应结果
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost:8081/")
.build();
Call call = okHttpClient.newCall(request);
// 该方法不会阻塞,通过设置回调方法来处理执行结果
call.enqueue(new Callback() {
// 处理异常
@Override
public void onFailure(Call call, IOException e) {
System.out.println(e.getMessage());
}
// 处理响应
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
System.out.println(response.body().string());
}
}
});
尽量通过Builder来构建各个组件
如你所见,上面的Demo中。几乎处处都用到了工厂模式。Builder可以通过一系列的链式调用方法来设置属性,最后通过
build()
方法来创建我们需要组件。比起直接new
出实例后,挨个设置要方便得多
OkHttpClient.Builder
其他的一些Builder就靠你自己去参阅源码或者文档了
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false) //禁止OkHttp的重定向操作,自己处理重定向
.followSslRedirects(false) //禁止ssl重定向(80 -> 443)
.cookieJar(new CookieJar() { //cookie的序列化与反序列化接口,需要自己实现
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return null;
}
})
.connectTimeout(Duration.ofMillis(2000)) // 设置连接超时时间
// .... 还有很多配置(拦截器,SSL,缓存,事件监听器,代理.....),可以参阅文档或者源码
.build();
在SpringBoot中使用OkHttp
最简单的整合就是把OkHttp的
OkHttpClient
交给IOC管理,在需要的地方注入。
SpringBoot
也提供了一个非常不错的Http客户端。RestTemplate
。而且在 SpringCloud
中都是靠它发起远程的rest
调用。RestTemplate
可以设置一个 ClientHttpRequestFactory
。它是一个接口,而且OkHttp
提供了对它的实现:okHttp3ClientHttpRequestFactory
RestTemplate restTemplate = new RestTemplate();
OkHttpClient okHttpClient = new OkHttpClient();
// 实例化OkHttp工厂类
OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory = new OkHttp3ClientHttpRequestFactory();
// 设置给RestTemplate
restTemplate.setRequestFactory(okHttp3ClientHttpRequestFactory);
看到这里,想必你在项目中使用Okhttp没问题了。