【笔记】Retrofit学习笔记

前言

A type-safe HTTP client for Android and Java.(Github

关于URL与URI

  • URI = URL + URN

创建发送请求接口

  • 根据需要发送的请求,创建一个接口,接口名自定义

常用的注解

<urn>:请求地址URI的URN部分(不含域名)
@GET(""):在接口上标注@GET("")表示发送GET请求,在注解参数中填写服务器接口请求地址,不需要涵盖域名
@Query(""):使用GET请求传递参数时,需要在参数前添加@Query()注解,注解内指定发送请求时的参数名
@POST(""):在接口上标注@POST("")表示发送POST请求,在注解参数中填写服务器接口请求地址,不需要涵盖域名
@Field(""):使用POST请求传递参数时,如果是FormUrlEncoded的方式,需要在参数前添加@Field()注解,注解内指定发送请求时的参数名

app/src/main/java/.../HttpBinService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;

public interface HttpBinService {

@GET("<urn>")
Call<ResponseBody> get(@Query("username") String username, @Query("password") String password);

@POST("<urn>")
@FormUrlEncoded
Call<ResponseBody> post(@Field("username") String username, @Field("password") String password);

}

Map注解

  • 当定义多个请求参数时,可以使用Map集合传递参数
app/src/main/java/.../HttpBinService.java
1
2
3
4
5
6
@GET("<urn>")
Call<ResponseBody> GET(@QueryMap Map<String, Object> map);

@POST("<urn>")
@FormUrlEncoded
Call<ResponseBody> POST(@FieldMap Map<String, Object> map);

@HTTP注解

  • @HTTP注解为更灵活的标注请求方式

利用@HTTP注解定义GET请求

method = "GET":定义请求方式
path = "":定义请求地址
hasBody = false:定义是否有请求体,默认不填为false

1
2
3
@HTTP(method = "GET", path = "<urn>")

@HTTP(method = "GET", path = "<urn>", hasBody = false)

利用@HTTP注解定义POST请求

method = "POST":定义请求方式
path = "":定义请求地址
hasBody = false:定义是否有请求体,默认不填为false

1
2
3
4
5
@HTTP(method = "POST", path = "<urn>")

@HTTP(method = "POST", path = "<urn>", hasBody = false)

@HTTP(method = "POST", path = "<urn>", hasBody = true)

@Path注解

  • 使用@Path注解可以实现向方法注解参数中传递变量

  • {}内的参数需要与@Path("")内的参数相对应

动态传递请求地址的URN部分

1
2
@HTTP(method = "", path = "{urn}")
Call<ResponseBody> get(@Path("urn") String urn);

与@HTTP注解配合实现动态请求方式

1
2
@HTTP(method = "{method}", path = "")
Call<ResponseBody> get(@Path("method") String method);

@Header注解与@Headers注解

@Header注解

  • @Header注解用于在形参中传递请求头的参数

key:请求头参数键
value:请求头参数值形参

1
2
@GET("<urn>")
Call<ResponseBody> get(@Header("key") String value);

@Headers注解

  • @Headers注解用于直接在方法上标注请求头所有参数
添加一个参数
1
2
3
@Headers("key:value")
@GET("<urn>")
Call<ResponseBody> get();
添加多个参数
1
2
3
@Headers({"key1:value1", "key2:value2"})
@GET("<urn>")
Call<ResponseBody> get();

创建Retrofit对象

  • 创建Retrofit对象,并生成接口实现类对象

<url>:请求地址URI的URL部分

发送GET请求

app/src/main/java/.../MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder().baseUrl("<url>").build();
// 通过Retrofit对象创建自定义接口的实现类对象
HttpBinService httpBinService = retrofit.create(HttpBinService.class);

// 通过接口实现类对象发送GET请求
Call<ResponseBody> responseBodyCall = httpBinService.get("", "");
responseBodyCall.enqueue(new Callback<ResponseBody>() {
// 请求成功的回调方法
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

// 请求失败的回调方法
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});

发送POST请求

app/src/main/java/.../MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder().baseUrl("<url>").build();
// 通过Retrofit对象创建自定义接口的实现类对象
HttpBinService httpBinService = retrofit.create(HttpBinService.class);

// 通过接口实现类对象发送POST请求
Call<ResponseBody> responseBodyCall = httpBinService.post("", "");
responseBodyCall.enqueue(new Callback<ResponseBody>() {
// 请求成功的回调方法
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

// 请求失败的回调方法
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});

POST请求传递JSON参数

通过JSON格式的字符串直接传递字符串

app/src/main/java/.../HttpBinService.java
1
2
3
@POST("<urn>")
@FormUrlEncoded
Call<ResponseBody> POST(@Field("") String json);

通过@Body注解传递RequestBody对象

  • 自定义请求体
app/src/main/java/.../HttpBinService.java
1
2
3
@POST("urn")
@FormUrlEncoded
Call<ResponseBody> POST(@Body RequestBody requestBody);

发送含有RequestBody的POST请求

app/src/main/java/.../MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 自定义请求体
FormBody body = new FormBody.Builder().add("", "").build();

Retrofit retrofit = new Retrofit.Builder().baseUrl("<url>").build();
HttpBinService httpBinService = retrofit.create(HttpBinService.class);
Call<ResponseBody> responseBodyCall = httpBinService.post(body);
responseBodyCall.enqueue(new Callback<ResponseBody>() {
// 请求成功的回调方法
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

// 请求失败的回调方法
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {

}
});

通过完整请求地址发送请求

  • 通过@Url注解,将完整请求地址URI以参数的形式传递

<uri>:完整的请求地址URI

定义接口

1
2
3
4
5
6
7
8
9
public interface HttpBinService {

@GET
Call<ResponseBody> get(@Url String uri);

@POST
@FormUrlEncoded
Call<ResponseBody> post(@Url String uri);
}

发送请求

发送GET请求

1
2
3
4
5
6
7
8
Retrofit retrofit = new Retrofit.Builder().baseUrl("").build();
HttpBinService httpBinService = retrofit.create(HttpBinService.class);
try {
Response<ResponseBody> response = httpBinService.get("<uri>").execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}

发送POST请求

1
2
3
4
5
6
7
8
Retrofit retrofit = new Retrofit.Builder().baseUrl("").build();
HttpBinService httpBinService = retrofit.create(HttpBinService.class);
try {
Response<ResponseBody> response = httpBinService.post("<uri>").execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}

Retrofit转换器

  • 通过使用Retrofit提供的转换器,将响应的JSON格式的字符传数据转换成Java对象

添加依赖

app/build.gradle
1
2
3
4
5
6
dependencies {

...

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}

创建一个实体类

  • 根据响应的数据格式,创建一个pojo类
1
2
3
4
5
public class Responce {

...

}

在接口中的泛型直接定义为实体类

1
2
3
4
5
6
public interface HttpBinService {

@GET("<urn>")
Call<Responce> get(@Query("username") String username, @Query("password") String password);

}

发送请求

  • 创建Retrofit对象时,添加转换器
1
2
3
4
5
6
7
8
9
10
// 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("<url>")
.converterFactory(GsonConverterFactory.create()) // 添加转换器
.build();
// 通过Retrofit对象创建自定义接口的实现类对象
HttpBinService httpBinService = retrofit.create(HttpBinService.class);

// 自动转换为Java对象
Responce responce = httpBinService.get("", "").execute().body();

文件上传下载

定义接口

@Part:此处也可以使用@PartMap注解实现多文件上传
@Streaming:文件下载时可以防止内存溢出

1
2
3
4
5
6
7
8
9
10
public interface HttpBinService {

@POST("<urn>")
@Multipart
Call<ResponseBody> post(@Part MultipartBody.Part file);

@GET("<urn>")
@Streaming
Call<ResponseBody> download();
}

文件上传下载

上传文件

<key>:请求参数键
<value>:请求参数值,通常为文件名

1
2
3
4
5
6
7
8
9
10
11
12
File file = new File("");
MultipartBody.Part part = MultipartBody.Part.createFormData("<key>", "<value>", RequestBody.create(MediaType.parse("text/plain"), file));

Retrofit retrofit = new Retrofit.Builder().baseUrl("<url>").build();
HttpBinService httpBinService = retrofit.create(HttpBinService.class);
Call<ResponseBody> call = httpBinService.upload(part);
try {
String result = call.execute().body().string();
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}

下载文件

<src>:文件存放的本地路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Retrofit retrofit = new Retrofit.Builder().baseUrl("<url>").build();
HttpBinService httpBinService = retrofit.create(HttpBinService.class);
Call<ResponseBody> call = httpBinService.download();
try {
Response<ResponseBody> response = call.execute();

if (response.isSuccessful()) {
/* 通过I/O流保存文件到本地 */
InputStream inputStream = response.body().byteStream();
FileOutputStream fos = new FileOutputStream("<src>");
int len;
byte[] buffer = new byte[4096];
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}

完成

参考文献

哔哩哔哩——Android架构解析