前言
Retrofit是一个封装的网络请求框架库,它是基于okHttp的,支持同步异步,通过动态代理的方式进行处理,使用大量的注解配置参数,比较简洁。Retrofit主要是负责封装接口,这一篇主要着重于介绍它的注释使用
一. 简介
二. 注解
1. 网络请求方法
2. 标记
3. 网络请求参数
Retrofit的注解写法
(1)GET请求使用
@Query
常用在地址后问号拼接的形式,例如http://192.168.1.12:80/xxx/customer/createXXX?name=拉莫帅
public interface ApiService {
/**
* 最简单的GET请求,无参数
*/
@GET(MyApi.cityWeather)
Observable<Weather> getInfo1();
/**
* GET请求,带请求参数
* 请求参数用@Query注解,其中注解里的名字表示追加到URL后的参数名字,
* URL后的参数值即为我们传进来的类型String name/int age
* 所以该请求完整的地址是host/api/fetch/guesslike?name=name&mAge=age
*/
@GET(MyApi.cityWeather)
Observable<Weather> getInfo2(@Query("name") String name, @Query("mAge") int age);
/**
* GET请求,带请求参数
* 对getInfo2的改进,多个参数可以用@ueryMap标记,都放到一个Map里
*/
@GET(MyApi.cityWeather)
Observable<Weather> getInfo3(@QueryMap Map<String, String> paramsMap);
/**
* GET请求,@Path标记的作用就是使用传进来的值动态替换URL里的字段{id}
*/
@GET(MyApi.cityWeather)
Observable<Weather> getInfo4(@Path("id") String id);
}
(2)POST请求使用
@Field
一般用于post请求,以form表单的形式传递数据,通常在接口上方还要搭配 @FormUrlEncoded 使用
@Body
通常用于提交json数据,我们的提交通常为一个实体对象,retrofit会帮助我们自动将对象转换为json提交
public interface ApiService {
/**
* POST请求
* 其中@FormUrlEncoded的含义是发送已编码的Form表单
* 加这个注解后,请求的Content-Type会是application/x-www-form-urlencoded;
* 加这个注解后,发送的参数必须是@Field标记的表单键值对
*/
@FormUrlEncoded
@POST(MyApi.HotVideo)
Observable<Video> getInfo5(@Field("sid") String id);
/**
* POST请求
* 和getInfo5没区别,@FieldMap仅仅表示多个请求参数可以放到一个Map里方便传递而已
*/
@FormUrlEncoded
@POST(MyApi.HotVideo)
Observable<Video> getInfo6(@FieldMap Map<String, String> map);
/**
* POST请求,但是没有使用Form表单的形式,即没有@FormUrlEncoded
* 那么请求的Content-Type默认会是application/json;
* 不添加@FormUrlEncoded,那么就不能用@Field进行传递参数了,只有一种形式就是@Body,它就是用于非表单的请求体
* retrofit会把请求的实体序列化成一个json发送出去
*/
@POST(MyApi.HotVideo)
Observable<Video> getInfo7(@Body CMMEntity requestEntity);
/**
* 和getInfo7一样,只是请求参数是官方的RequestBody
* 这样做的好处是,我们自己构建的RequestBody可以修改其Media-Type
*/
@POST(MyApi.HotVideo)
Observable<Video> getInfo8(@Body RequestBody requestBody);
// 生成RequestBody
RequestBody getRequestBodyForParams(Map<String, String> paramsMap) {
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
JSONObject jo = new JSONObject();
if (paramsMap != null) {
for (String key : paramsMap.keySet()) {
try {
jo.put(key, paramsMap.get(key));
} catch (JSONException e) {
}
}
}
return RequestBody.create(mediaType, jo.toString());
}
//RequestBody实战
public void updateEnquimentDevices(String equipmentMacAddress,String id){
paramsMap = new HashMap<>();
paramsMap.put("equipmentMacAddress",equipmentMacAddress);
paramsMap.put("id",id);
String strEntity = gson.toJson(paramsMap);
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"),strEntity);
addDisposable(apiServer.getUpdateEquipentUser(body), new BaseObserver<JsonData>(baseView,true) {
@Override
public void onSuccess(JsonData o) {
baseView.onattentionSuccess(o);
}
@Override
public void onError(String msg) {
baseView.showError(msg);
}
@Override
public void onErrorCode(int code, String msg) {
baseView.onErrorCode(code,msg);
}
});
}
}
(3)HTTP/URL/Streaming标签使用
@Streaming
指响应体的数据以流的形式返回,如果不使用默认会把数据全部加载到内存,所以下载文件时需要加上这个注解
public interface ApiService {
/**
* 下面定义了一个Delete请求,其实@HTTP标签是可以替代所有的请求标签,包括GET/POST/PUT/DELETE等,
* 都可以通过@HTTP标签来实现。hasBody表示是否有请求体,有就用参数@Body带上
*/
@HTTP(method = "DELETE", path = "api/fetch/guesslike/{id}", hasBody = true)
Observable<GuessLikeEntity> getInfo9(@Path("id") String id, @Body CMMEntity requestEntity);
/**
* 当有@URL注解时,@GET传入的URL就可以省略
*/
@GET
Observable<GuessLikeEntity> getInfo16(@Url String url);
/**
* 其中@Streaming注解表示返回的数据以流的形式返回,适用于大文件的下载操作。
* 如果没有该注解,会默认把数据全部载入到内存里,即将将body()转换为byte[],就有可能引起OOM了
*/
@Streaming
@GET
Observable<ResponseBody> getInfo17(@Url String url);
// 获取返回的数据处理
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();
}
(4)Header标签使用
public interface ApiService {
/**
* GET请求,@Headers的作用是添加单个固定的请求头
*/
@Headers("Cache-Control: max-age=640000")
@GET("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo10();
/**
* GET请求,@Headers添加了多个固定的请求头
*/
@Headers({"Cache-Control: max-age=640000", "Accept-Charset: UTF-8"})
@GET("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo11();
/**
* GET请求,@Header是用在参数上,添加单个不固定的请求头,值由外部传进来
*/
@GET("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo12(@Header("Accept-Charset") String charset);
/**
* GET请求,@HeaderMap是用在参数上,添加多个不固定的请求头,键和值都是由外部传进来
*/
@GET("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo13(@HeaderMap Map<String, String> headerMap);
}
(5)Multipart/Part标签使用
@Multipart
表示发送form-encoded的数据(适用于 有文件 上传的场景),每个键值对需要用@Part来注解键名,随后的对象需要提供值。
此注解方法,并用@Part注解方法参数,类型是List< okhttp3.MultipartBody.Part>
不使用@Multipart注解方法,直接使用@Body注解方法参数,类型是okhttp3.MultipartBody
public interface ApiService {
/**
* POST请求
* 其中@Multipart表示请求体是分为多个部分的,配合参数@Part使用。
* 如果@Part的参数类型是RequestBody,表示请求参数,那么其Key,也就是"name"和"age"是不能隐藏的,必须显式指明Key
* 如果@Part的参数类型是MultipartBody.Part,即表示请求的上传文件,内容会直接被使用,那么是不需要Key的
*/
@Multipart
@POST("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo14(@Part("name") RequestBody name, @Part("age") RequestBody age,
@Part MultipartBody.Part file);
/**
* POST请求,getInfo14的改良版。多个请求参数可以封装在@PartMap标记对应的Map里
*/
@Multipart
@POST("api/fetch/guesslike")
Call<GuessLikeEntity> getInfo15(@PartMap Map<String, RequestBody> paramsMap ,
@Part MultipartBody.Part file);
}