Retrofit 2 网络请求框架的使用简介
简介
.
.
添加Retrofit 2及其相关的依赖
dependencies {
// Retrofit库
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//Okhttp3 网络请求框架
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
//Gson
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
}
在AndroidManifest.xml中声明一下网络权限才行:
<uses-permission android:name="android.permission.INTERNET" />
.
.
Retrofit 2 的简单使用
使用步骤:
1. 创建 接收服务器返回数据 的类
2. 创建 用于描述网络请求 的接口
3. 创建 Retrofit 实例
4. 创建 网络请求接口实例 并 配置网络请求参数
5. 发送网络请求(异步 / 同步)
1. 创建数据接收类(Bean类)
public class JavaBean {
...
// 根据返回数据的格式和数据解析方式(Json、XML等)定义字段
}
2. 创建描述网络请求的接口
目的: Retrofit将 Http请求 抽象成 Java接口:采用 注解 描述网络请求参数 和配置网络请求参数
注: 接口中的每个方法的参数都需要使用注解标注,否则会报错
public interface RequestInterface {
// @GET注解的作用:采用Get方法发送网络请求
@GET("请求地址域名的后半部分")
/*
*getCall():表示接收网络请求数据的方法
* Call<*>:*是接收数据的类(即上面定义的JavaBean类)
* */
Call<JavaBean> getCall();
}
3. 创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器(使用Gson解析数据)
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava平台
.build();
4. 创建 网络请求接口实例
// 创建 网络请求接口 的实例
RequestInterface request = retrofit.create(RequestInterface.class);
//对 发送请求 进行封装
Call<JavaBean> call = request.getCall();
5. 发送网络请求(异步 / 同步)
//发送网络请求(异步)
call.enqueue(new Callback<JavaBean>() {
//请求成功时回调
@Override
public void onResponse(Call<JavaBean> call, Response<JavaBean> response) {
//打印请求结果
Log.d("TAG","响应的结果"+ response.body().show());
}
//请求失败时候的回调
@Override
public void onFailure(Call<JavaBean> call, Throwable throwable) {
//进行请求失败的相关处理
}
});
// 发送网络请求(同步)
Response<JavaBean> response = call.execute();
if (response.isSuccessful()) {
//请求成功
Log.d("TAG","响应的结果"+ response.body().show());
}else{
//请求失败
}
.
.
Retrofit 请求的接口的注解的介绍(重点)
1. 网络请求方法注解:
@GET: 表明这是get请求
@POST: 表明这是post请求
@PUT: 表明这是put请求
@DELETE: 表明这是delete请求
@PATCH: 表明这是一个patch请求,该请求是对put请求的补充,用于更新局部资源
@HEAD: 表明这是一个head请求
@OPTIONS : 表明这是一个option请求
@HTTP: 通用注解,可以替换以上所有的注解,其拥有三个属性:method,path,hasBody
method : 网络请求的方法(区分大小写);
path : 网络请求地址路径 ;
hasBody : 是否有请求体
详细说明与使用
注:
网络请求的完整 Url = baseUrl()设置 + 网络请求接口的注解设置(下面称 “path“ )具体整合的规则如下:
- @GET、@POST、@PUT、@DELETE、@HEAD注解使用类似于@GET
public interface RequestInterface {
// @GET注解的作用:采用Get方法发送网络请求
@GET("请求地址域名的后半部分") //替换相应的请求方法
/*
*getCall():表示接收网络请求数据的方法
* Call<*>:*是接收数据的类(即上面定义的JavaBean类)
* */
Call<JavaBean> getCall();
}
- @HTTP注解
作用: 替换 @GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展
public interface RequestInterface {
/**
* method:网络请求的方法(区分大小写)
* path:网络请求地址路径
* hasBody:是否有请求体
* {id} 表示是一个变量
* method 的值 retrofit 不会做处理,所以要自行保证准确
*/
@HTTP(method = "GET", path = "blog/{id}", hasBody = false)
Call<JavaBean> getCall(@Path("id") int id);
}
.
2. 标记注解:
@FormUrlEncoded: 表示请求发送编码表单数据,每个键值对需要使用@Field注解
@Multipart : 表示请求发送multipart数据,需要配合使用@Part
@Streaming: 表示响应用字节流的形式返回
注: 如果没使用该注解,默认会把数据全部载入到内存中,之后获取数据也是从内存中读取。该注解在在下载大文件的特别有用
@FormUrlEncoded:
public interface RequestInterface {
/**
*表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
*@Field("username")表示: 将后面的 String name中name的取值作为 username 的值
*/
@POST("/form")
@FormUrlEncoded
Call<JavaBean> MyFormUrlEncoded( @Field("id") long id,@Field("username") String name);
}
// 创建 网络请求接口 的实例
RequestInterface request = retrofit.create(RequestInterface.class);
//对 发送请求 进行封装(@FormUrlEncoded )
Call<ResponseBody> call1 = retrofit.MyFormUrlEncoded(5201314,"萝莉");
// 发送网络请求(同步)
Response<JavaBean> response = call.execute();
@Multipart:
public interface RequestInterface {
@Multipart
Call<ResponseBody> MyFileUpload(@Part("name") RequestBody name, @Part MultipartBody.Part file);
}
// 创建 网络请求接口 的实例
RequestInterface request = retrofit.create(RequestInterface.class);
File file = new File(url);
//构建requestbody
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//将resquestbody封装为MultipartBody.Part对象
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file",file);
//对 发送请求 进行封装(@FormUrlEncoded )
Call<JavaBean> call = request.MyFileUpload(filePart);
// 发送网络请求(同步)
Response<JavaBean> response = call.execute();
.
3. 网络请求参数注解:
(1) @Header
作用: 作为方法的参数传入,用于添加不固定的header,它会更新已有请求头
使用:
public interface RequestInterface {
@GET("请求地址的一部分")
Call<JavaBean> getCall(@Header("token") token);
}
(2) @Headers
作用: 用于添加固定请求头,可以同时添加多个,通过该注解的请求头不会相互覆盖,而是共同存在
使用:
public interface RequestInterface {
@Headers("Cache-Control: max-age=64000")
@GET("请求地址的一部分")
Call<JavaBean> getCall();
}
当然@Header也支持同时设置多个:
public interface RequestInterface {
@Headers({
"version:1.0.0"
"Cache-Control: max-age=64000"
})
@GET("请求地址的一部分")
Call<JavaBean> getCall();
}
(3) @Url
作用: 指定请求路径,可以当做参数传入
使用:
public interface RequestInterface {
// 当有URL注解时,@GET传入的URL就可以省略
// 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供
@GET
Call<JavaBean> getCall(@Url String url, @Query("id") int id);
}
(4) @Body:
作用: 多用于Post请求发送非表达数据,根据转换方式将实例对象转化为对应字符串传递参数,比如使用Post发送Json数据,添加GsonConverterFactory则是将body转化为json字符串进行传递
使用:
1. 创建Bean类
public class JavaBean2{
...
}
2. 创建网络请求的接口
public interface RequestInterface {
@POST("请求地址的一部分")
Call<JavaBean> getCall(@Body JavaBean2 bean);
}
3. 将JavaBean2对象映射成json数据再发送给服务器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器(使用Gson解析数据)
.build();
(5) @Filed 和 @FiledMap:
作用: 多用于Post方式传递表单字段,需要结合@FromUrlEncoded使用,即以表单的形式传递参数
使用:
1. @Filed的使用
public interface RequestInterface {
@POST("请求地址的一部分")
@FormUrlEncoded
Call<JavaBean> getCall(@Field("username") String name, @Field("age") int age);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器(使用Gson解析数据)
.build();
// 创建 网络请求接口 的实例
RequestInterface request = retrofit.create(RequestInterface.class);
//对 发送请求 进行封装
Call<JavaBean> call = request.getCall("萝莉",16);
2. @FiledMap的使用
public interface RequestInterface {
@POST("请求地址的一部分")
@FormUrlEncoded
Call<JavaBean> getCall(@FieldMap Map<String, Object> map);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器(使用Gson解析数据)
.build();
// 创建 网络请求接口 的实例
RequestInterface request = retrofit.create(RequestInterface.class);
//对 发送请求 进行封装
Map<String, Object> map = new HashMap<>();
map.put("username", "萝莉");
map.put("age", 16);
Call<JavaBean> call = retrofit.getCall(map);
(6) @Part 和 @PartMap:
作用: 用于Post方式传递表单字段,Part和PartMap与@multipart注解结合使用,适合文件上传的情况
注:
与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 文件上传的场景
使用:
1. @Part的使用
public interface RequestInterface {
@POST("请求地址的一部分")
@Multipart
Call<JavaBean> getCall(@Part("name") RequestBody name, @Part MultipartBody.Part file);
}
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "萝莉");
RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "文件的内容");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file);
Call<JavaBean> call = request.getCall(name,filePart);
ResponseBodyPrinter.printResponseBody(call);
2. @PartMap的使用
public interface RequestInterface {
@POST("请求地址的一部分")
@Multipart
Call<JavaBean> getCall(@PartMap Map<String,JavaBean> args);
}
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "萝莉");
RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "文件的内容");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file);
Map<String, RequestBody> map = new HashMap<>();
map.put("name", name);
map.put("age", age);
Call<JavaBean> call = retrofit.getCall(map, filePart); //单独处理文件
ResponseBodyPrinter.printResponseBody(call);
(7) @Path:
作用: Url地址的缺省值,可以替换url中的值
使用:
// 访问的API是:https://api.github.com/users/{user}/repos
public interface RequestInterface {
// 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用)
@GET("users/{user}/repos")
Call<JavaBean> getCall(@Path("user") String user );
}
(8) @Query 和 @QueryMap:
作用: 用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)
使用:
如:url = https://www.baidu.com/?username=luoli
其中,Query = username
public interface RequestInterface {
@GET("/")
Call<JavaBean> getCall(@Query("username") String name);
}
Retrofit注解的具体使用
1. 提交json格式数据(使用@Body注解)
( 1 ) 创建需要上传的RegisterPost
public class RegisterPost {
private String username;
private int age;
...
}
( 2 ) 创建请求接口
public interface RequestInterface {
@POST("mobile/register")
Call register(@Body RegisterPost post);
}
( 3 ) 在Activity中发送网络请求
.
2. 上传文件(使用 @Multipart和@Part 注解)
( 1 ) 创建请求接口
- 单个文件上传
public interface RequestInterface {
@Multipart
@POST("mobile/upload")
Call<JavaBean> upload(@Part MultipartBody.Part file);
}
- 多个文件上传
public interface RequestInterface {
@Multipart
@POST("upload/upload")
Call<JavaBean> upload(@PartMap Map<String, MultipartBody.Part> map);
}
- 图文混传
public interface RequestInterface {
@Multipart
@POST("")
Call<JavaBean> register(@Body RegisterPost post,@Part MultipartBody.Part image);
}
( 1 ) 在Activity中发送网络请求
File file = new File(url);
//构建requestbody
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//将resquestbody封装为MultipartBody.Part对象
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
.
.
Retrofit的 数据解析器 和 网络请求适配器 的介绍
1. 关于数据解析器(Converter)
-
Retrofit支持多种数据解析方式
-
使用时需要在Gradle添加依赖
数据解析器 | Gradle依赖 |
---|---|
Gson | com.squareup.retrofit2:converter-gson:2.0.2 |
Jackson | com.squareup.retrofit2:converter-jackson:2.0.2 |
Simple XML | com.squareup.retrofit2:converter-simplexml:2.0.2 |
Protobuf | com.squareup.retrofit2:converter-protobuf:2.0.2 |
Moshi | com.squareup.retrofit2:converter-moshi:2.0.2 |
Wire | com.squareup.retrofit2:converter-wire:2.0.2 |
Scalars | com.squareup.retrofit2:converter-scalars:2.0.2 |
数据解析器的使用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器(使用Gson解析数据)
.build();
.
2. 关于网络请求适配器(CallAdapter)
-
Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava
-
使用时需要在Gradle添加依赖:
数据解析器 | Gradle依赖 |
---|---|
android | 默认 |
rxjava | com.squareup.retrofit2:adapter-rxjava:2.0.2 |
Java8 | com.squareup.retrofit2:adapter-java8:2.0.2 |
guava | com.squareup.retrofit2:adapter-guava:2.0.2 |
数据解析器的使用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("请求地址域名部分") // 设置网络请求的Url地址
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava平台
.build();
.
.
拦截器Interceptors使用
Retrofit 2.0 底层强制依赖okHttp,所以可以使用okHttp的拦截器Interceptors 来对所有请求进行再处理,可以通过阅读我之前的文章来了解具体的使用方法。