一:介绍
- OkHttp是一个处理网络请求的开源框架。
- Retrofit是一个基于OkHttp的可以用于Android和java的网络库。
- RxJava是一个基于事件订阅的异步执行的一个类库。
二:简单实例,无任何封装
public class RetrofitExample {
//对应服务器的API接口
private interface IStores {
@GET("api/tms/tmsUser/updateToke")
Call<JsonObject> updateToke1(@Query("toke") String toke);
@FormUrlEncoded
@POST("api/tms/tmsUser/updateToke")
Observable<JsonObject> updateToke2(@Field("toke") String toke);
}
//Retrofit自带的Call回调
public static void updateToke1() {
new Retrofit.Builder()
.baseUrl("http://www.test.mulacar.cn:8080/")
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient())
.build()
.create(IStores.class)
.updateToke1("123456")
.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
JsonObject jsonObject = response.body();
Log.e("onResponse", jsonObject.toString());
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
t.printStackTrace();
}
});
}
//Retrofit与RxJava配合使用
public static void updateToke2() {
new Retrofit.Builder()
.baseUrl("http://www.test.mulacar.cn:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
.create(IStores.class)
.updateToke2("123456")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<JsonObject>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(JsonObject value) {
Log.e("onResponse", value.toString());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
}
});
}
}
思考???
- API接口中的各项注解的功能,与HTTP协议的联系?
- 如何构建Retrofit对象,他有哪些功能?
- 如何构建retrofit需要的OkHttp对象,哪些业务可以利用OkHttp来完成?
- retrofit如何与RxJava关联起来,哪些业务可以利用RxJava来完成?
三:Retrofit注解
请求方法注解
GET注解
- 表示发送一个GET请求。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个GET请求。
POST注解
- 表示发送一个POST请求。
@POST("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个POST请求。
HEAD注解
- 表示发送一个HEAD请求。
@HEAD("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke1();
- 表示发送一个HEAD请求。
DELETE注解
- 表示发送一个DELETE请求。
@DELETE("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个DELETE请求。
PUT注解
- 表示发送一个PUT请求。
@PUT("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个PUT请求。
OPTIONS注解
- 表示发送一个OPTIONS请求。
@OPTIONS("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个OPTIONS请求。
PATCH注解
- 表示发送一个PATCH请求。
@PATCH("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke();
- 表示发送一个PATCH请求。
HTTP注解
- 表示发送一个自定义的HTTP请求。
@HTTP(method = "DELETE", path = "api/tms/tmsUser/updateToke", hasBody = false) Observable<JsonObject> updateToke();
- 表示发送一个自定义的HTTP请求。
请求参数注解
Query注解
- 用于给请求添加参数,参数以键值对拼接在路径后面。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Query("toke") String toke );
- 用于给请求添加参数,参数以键值对拼接在路径后面。
QueryMap注解
- 用于给请求添加参数集合,参数以键值对拼接在路径后面。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @QueryMap Map<String, Object> params );
- 用于给请求添加参数集合,参数以键值对拼接在路径后面。
QueryName注解(新增)
- 用于给请求添加参数,参数只有值,拼接在路径后面。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @QueryName String toke );
- 用于给请求添加参数,参数只有值,拼接在路径后面。
Field注解
- 用于给请求添加参数,参数以键值对放在body中。
@FormUrlEncoded @POST("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Field("toke") String toke );
- 用于给请求添加参数,参数以键值对放在body中。
FieldMap注解
- 用于给请求添加参数集合,参数以键值对放在body中。
@FormUrlEncoded @POST("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @FieldMap Map<String, Object> params );
- 用于给请求添加参数集合,参数以键值对放在body中。
Part注解
- 用于给请求添加参数,参数以表单形式放在body中。
@Multipart @POST("api/tms/tmsUser/upaVatar") Observable<ApiResult<Driver>> uploadAvatar( @Part("type") int type );
- 用于给请求添加参数,参数以表单形式放在body中。
PartMap注解
- 用于给请求添加参数集合,参数以表单形式放在body中。
@Multipart @POST("api/tms/tmsUser/upaVatar") Observable<ApiResult<Driver>> uploadAvatar( @PartMap Map<String, RequestBody> params );
- 用于给请求添加参数集合,参数以表单形式放在body中。
Path注解
- 用于替换请求路径中的参数。
@GET("api/tms/{what}/updateToke") Observable<JsonObject> updateToke( @Path("what") String toke );
- 用于替换请求路径中的参数。
Body注解
- 将一个Java类的属性转换为参数,支持POST和PUT请求。
//实体 class Repo { final String owner; final String name; Repo(String owner, String name) { this.owner = owner; this.name = name; } } //接口 @POST("api/tms/{what}/updateToke") Observable<ResponseBody> updateToke( @Body Repo repo );
- 将一个Java类的属性转换为参数,支持POST和PUT请求。
Header注解
- 添加一个请求头参数。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Header("aaa") String aaa, @Query("toke") String toke );
- 添加一个请求头参数。
HeaderMap注解(新增)
- 添加一个请求头参数集合。
@GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Header("aaa") String aaa, @Query Map<String, Object> params );
- 添加一个请求头参数集合。
Headers注解
- 添加一个请求头参数集合(写死)。
@Headers({ "Cache-Control: max-age=640000","aaa: bbb"}) @GET("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Query("toke") String toke );
- 添加一个请求头参数集合(写死)。
其他注解
FormUrlEncoded注解
- 当用了Field或FieldMap注解时,需要使用FormUrlEncoded注解。
@FormUrlEncoded @POST("api/tms/tmsUser/updateToke") Observable<JsonObject> updateToke( @Field("toke") String toke );
- 当用了Field或FieldMap注解时,需要使用FormUrlEncoded注解。
Multipart注解
- 表示以表单方式上传。
@Multipart @POST("api/tms/tmsUser/upaVatar") Observable<ApiResult<Driver>> uploadAvatar( @Part("type") int type );
- 表示以表单方式上传。
Streaming注解
- 表示直接获取输入流,下载文件时要用到此参数,如果不加此注释,则会把整个文件写入内存,那么大文件会内存溢出。
@Streaming @GET("api/tms/tmsUser/download") Call<ResponseBody> download( @QueryMap Map<String, Object> params );
- 表示直接获取输入流,下载文件时要用到此参数,如果不加此注释,则会把整个文件写入内存,那么大文件会内存溢出。
Url注解
- 添加请求路径,一般已经在请求方法注解中添加了请求路径,不用再使用此注解。
@GET Observable<JsonObject> updateToke( @Url String url );
- 添加请求路径,一般已经在请求方法注解中添加了请求路径,不用再使用此注解。
四:构建Retrofit对象
new Retrofit.Builder()
.baseUrl("http://www.test.mulacar.cn:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//.client(new OkHttpClient())
//.callbackExecutor(Executors.newCachedThreadPool())
//.validateEagerly(true)
//.callFactory(myFactory)
.build();
baseUrl(String baseUrl)
- 设置请求路径
- 当baseUrl只有域名,或者域名+端口时,末尾可以加/,也可以不加/
- 当baseUrl包含有除了域名的其他路径是,必须以/结尾。
- 当接口方法中的路径以/开头时,表示只取baseUrl得域名和端口,后面的路径忽略。
- 例如当baseUrl为”http://www.test.mulacar.cn:8080/api/“时
- 如果使用@GET(“/tms/tmsUser/updateToke”),那么实际的请求连接为http://www.test.mulacar.cn:8080/tms/tmsUser/updateToke
- 当接口方法中的路径没有以/开头时,表示取全部baseUrl。
- 例如当baseUrl为”http://www.test.mulacar.cn:8080/api/“时
- 如果使用@GET(“tms/tmsUser/updateToke”),那么实际的请求连接为http://www.test.mulacar.cn:8080/api/tms/tmsUser/updateToke
addConverterFactory(Converter.Factory factory)
- 设置转换工厂,用来转换发送和接收的数据。
- 官方给我们提供了一些转换器。
- GSON: com.squareup.retrofit:converter-gson:2.0.0-beta2
- Moshi: com.squareup.retrofit:converter-moshi:2.0.0-beta2
- Jackson: com.squareup.retrofit:converter-jackson:2.0.0-beta2
- SimpleXML: com.squareup.retrofit:converter-simplexml:2.0.0-beta2
- ProtoBuf: com.squareup.retrofit:converter-protobuf:2.0.0-beta2
- Wire: com.squareup.retrofit:converter-wire:2.0.0-beta2
自定义转换器。
- 参考类com.mula.retrofit.ConverterFactory
/** * 转换工厂, 将http返回结果转换为ApiResult */ public final class ConverterFactory extends Converter.Factory { public static ConverterFactory create() { return new ConverterFactory(); } private ConverterFactory() { } @Override public Converter<?, RequestBody> requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return new BeanRequestBodyConverter<>(type); } @Override public Converter<ResponseBody, ?> responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return new BeanResponseBodyConverter<>(type); } static final class BeanRequestBodyConverter<T> implements Converter<T, RequestBody> { private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); private final Type type; public BeanRequestBodyConverter(Type type) { this.type = type; } @Override public RequestBody convert(T value) throws IOException { String str = new Gson().toJson(value, type); return RequestBody.create(MEDIA_TYPE, str); } } static final class BeanResponseBodyConverter<T> implements Converter<ResponseBody, ApiResult<T>> { private final Type type; public BeanResponseBodyConverter(Type type) { this.type = type; } @Override public ApiResult<T> convert(ResponseBody value) throws IOException { String responseStr = value.string(); L.e("result:" + responseStr); ApiResult<T> apiResult; try { JsonObject jsonObject = new JsonParser().parse(responseStr).getAsJsonObject(); String code = jsonObject.get("code").getAsString(); if ("success".equals(code)) { apiResult = new Gson().fromJson(responseStr, type); } else { apiResult = new ApiResult<>(); apiResult.setType(false); apiResult.setCode(code); apiResult.setMessage(jsonObject.get("message").getAsString()); } } catch (Exception e) { e.printStackTrace(); apiResult = new ApiResult<>(); apiResult.setStatus(ApiResult.Status.ERROR_JSON); apiResult.setMessage("json_error"); } apiResult.setJsonStr(responseStr); return apiResult; } } }
addCallAdapterFactory(CallAdapter.Factory factory)
- 设置回调适配器,默认的CallAdapter是返回一个Call对象。
使用RxJava的CallAdapter
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
使用RxJava2的CallAdapter(注意多了一个2)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
client(OkHttpClient client)
- 设置自定义OkHttpClient对象。
- 具体OkHttpClient的定义参考下面第五大条。
callFactory(okhttp3.Call.Factory factory)
- 用来处理okhttp的Request对象
validateEagerly(boolean validateEagerly)
- 调用生成的实例时,急切地验证所提供的接口中所有方法的配置,默认为false。
- 即当Retrofit的create方法调用时,是否验立刻证接口中的所以方法的配置。
callbackExecutor(Executor executor)
- 设置从服务方法返回结果的执行线程池。
- 但当调用了addCallAdapterFactory方法,设置了自己的回调适配器时,该方法将失效。
五:构建OkHttp对象
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)// 连接失败重连,默认为true,可以不加
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)// 链接超时
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)// 写入超时
.readTimeout(TIMEOUT, TimeUnit.SECONDS)// 读取超时
.cookieJar(new CookiesManager())// 开启cookie功能,将cookie序列化到本地
//.sslSocketFactory(new SSLSocketFactory())// 可以用来支持https协议
.addInterceptor(new AppInterceptor())// 添加自定义拦截操作
.build();
六:与RxJava联合使用
1.Retrofit需要设置addCallAdapterFactory为RxJava2CallAdapterFactory.create()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
2.接口的返回值需要定义为Observable<T>,返回的便是RxJava中的Observable
@FormUrlEncoded
@POST("api/tms/tmsUser/updateToke")
Observable<JsonObject> updateToke(@Field("toke") String toke);
3.完整实例
new Retrofit.Builder()
.baseUrl("http://www.test.mulacar.cn:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()// 创建Retrofit
.create(IStores.class)// 创建请求接口
.updateToke2("123456")// 调用接口方法,此处返回Observable,以下代码完全为RxJava的用法
.subscribeOn(Schedulers.newThread())// 切换到子线程发起网络请求
.observeOn(AndroidSchedulers.mainThread())// 订阅的返回结果切换到主线程
.subscribe(new Observer<JsonObject>() {
@Override
public void onSubscribe(Disposable d) {
// 此处的Disposable可以用来取消返回结果的订阅
}
@Override
public void onNext(JsonObject value) {
// 此处拿到返回的结果
Log.e("onResponse", value.toString());
}
@Override
public void onError(Throwable e) {
// 此处为发生错误回调
e.printStackTrace();
}
@Override
public void onComplete() {
// 完成
}
});
}