持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
一. 基本的组件 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请求 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 cookies) { } @Override public List 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);