文章目录
1 OkHttp主要的类
-
Request:构建HTTP请求,由Request.Builder创建,需要传入HTTP请求的url、请求类型等构建
-
Response:HTTP返回结果,可以获取HTTP请求从服务器拿到的数据,比如返回码、json数据
-
FormBody:构建POST请求表单请求体,由FormBody.Builder创建,FormBody传入的键值对数据
-
RequestBody:构建POST请求体,RequestBody是一个抽象类,通过RequestBody.create()创建,可以上传文件或json数据
-
MultipartBody:由MultipartBody.Builder创建,可以同时上传表单和文件、json数据,即FormBody和RequestBody的集合
-
OkHttpClient:发送HTTP请求的客户端,需要传入Request发送请求
2 GET请求
2.1 GET同步请求(需要开启子线程执行耗时操作)
public void test() {
Executors.newFixedThreadPool().execute(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
// 默认使用GET请求
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
Response response = client.newCall(reqeust).execute();
if (response.isSuccessful()) {
Log.i(TAG, "response code:" + response.code());
Log.i(TAG, "response message:" + response.message());
Log.i(TAG, "response body:" + response.body().string());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// 打印结果:
response code:200
response message:OK
response body:{'code':200,'message':success}
注意事项:
-
response.code()返回的是HTTP的响应码,服务器的响应码在response.body().string()返回的json中返回,要有所区分
-
response.body().string()只能调用一次,第一次调用时有返回值,第二次调用时返回null。因为response.body().string()本质时输入流的读操作,必须有服务器的输出流的写操作时客户端的读操作才能得到数据,而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,第二次将返回null
2.2 GET异步请求
public void test() {
OkHttpclient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
client.newCall(request).equeue(new Callback(){
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onReponse(Call call, Response response) throws IOException {
if (response.isSuccessful() {
Log.i(TAG, "response code:" + response.code());
Log.i(TAG, "response body:" + response.body().string());
}
}
});
}
3 POST请求
3.1 POST表单请求(FormBody)
public void test() {
OkHttpClient client = new OkHttpClient();
FormBody formBody = new FormBody.Builder()
.add("username", "vincent")
.build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(formBody)
.build();
client.newCall(request).equeue(new Callbac() {});
}
3.2 POST传递json或File对象(RequestBody)
public void test() {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
String json = "{\"username:\":\"vincent\"}";
RequestBody requestBody = RequestBody.create(mediaType, json);
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();
client.newCall(request).equeue(new Callback() {});
}
public vodi test() {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("File/*");
File file = new File("path");
RequestBody requestBody = RequestBody.create(mediaType, file);
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();
client.newCall(request).equeue(new Callback() {});
}
3.3 POST同时上传表单和文件数据(MultipartBody)
public void test() {
MediaType mediaType = MediaType.parse("File/*");
File file = new File("path");
RequestBody requestBody = RequestBody.create(mediaType, file);
OkHttpClient client = new OkHttpClient();
MultipartBody multipartBody = new MultipartBody()
.setType(MultipartBody.FORM)
.addFormDataPart("groupId", groupId)
.addFormDataPart("title", title)
.addFormDataPart("file", file.getName(), requestBody);
.build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(multipartBody)
.build();
client.newCall(request).equeue(new Callbac() {});
}
4 自定义RequestBody
public class CustomRequestBody extends RequestBody {
@Override
public MediaType contentType() {
return null;
}
// 重写了write,Sink是Okio包中的输出流,自定义实现上传流的功能
@Override
public void writeTo(BufferedSink sink) throws IOException {
FileInputStream fis = new FileInputStream(new File("path"));
byte[] buffer = new byte[1024*8];
if (fis.read(buffer) != -1) {
sink.write(buffer);
}
}
}
public void test() {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new CustomRequestBody();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();
client.newCall(request).equeue(new Callback() {});
}
5 设置请求头
public void test() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.header("User-Agent", "xxxx")
.addHeader("token", "testToken")
.build();
client.newCall(request).equeue(new Callback() {});
}
6 使用OkHttp下载文件
OkHttp中并没有提供下载文件的功能,但是在response可以获取流对象,将response的流写到本地就可以实现文件的下载,配合RandomAccessFile可以实现断点下载功能。
public void test() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com/xxxx.jpg")
.build();
client.newCall(request).equeue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
writeFileToLocal(response.body.byteStream());
}
}
});
}
public void writeFileToLocal(InputStream is) {
File localFile = new File("path");
FileOutputStream fos = new FileOutputStream(localFile);
byte[] buffer = new byte[1024*8];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
fos.close();
}