Retrofit是Square开发的一个用于网络请求的开源库,其实就是对okhttp进行更进一步封装。
retrofit在gradle中的配置:
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'//我这里还使用了rxjava
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
保存cookie和同步cookie拦截器,等会初始化retrofit用到:
/**
* 保存cookie和同步cookie拦截器
* Created by Administrator on 2017/9/5.
*/
class GetCookiesInterceptor implements Interceptor {
private Context context;
public static final String SP_NAME = "SharedPreferencesName";
GetCookiesInterceptor(Context context) {
super();
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
SharedPreferences mSharedPreferences=context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
String str = mSharedPreferences.getString(key, null)
if (StringUtils.isNotEmpty(str)) {
Type type = new TypeToken<List<String>>() {
}.getType();
List<String> list = new Gson().fromJson(str, type);
for (String s : list) {
L.d(s);
builder.addHeader("cookie", s);//统一添加这里有多少就传多少(多cookie)
}
}
Response response = chain.proceed(builder.build());
List<String> cookie = response.headers("Set-Cookie");
if (!cookie.isEmpty()) {//保存cookie
SharedPreferences mSharedPreferences=context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
mSharedPreferences.edit().putString(Contact.COOKIE, new Gson().toJson(cookie)).apply();
}
return response;
}
}
自定义转换器:
/**
* 自定义转换器
* Add myConverter factory for serialization and deserialization of objects.
* Created by Administrator on 2017/9/5.
*/
public class MGsonConverterFactory extends Converter.Factory {
private boolean isAes;
private Gson gson;
public static MGsonConverterFactory create(boolean isAes) {
return new MGsonConverterFactory(isAes);
}
private MGsonConverterFactory(boolean isAes) {
this.isAes = isAes;
gson = new Gson();
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new RequestBodyConverter<>(isAes, gson);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new ResponseBodyConverter<>(type, isAes);
}
/**
* 自定义请求RequestBody
*/
public static class RequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/wxt;charset=UTF-8");
private static final MediaType MEDIA_TYPE1 = MediaType.parse("application/json;charset=UTF-8");
private boolean isAes;
private Gson gson;
public RequestBodyConverter(boolean isAes, Gson gson) {
this.isAes = isAes;
this.gson = gson;
}
@Override
public RequestBody convert(T value) throws IOException {//T就是传入的参数
if (isAes) {//这里加上你自己的加密处理
AES aes = new AES();
return RequestBody.create(MEDIA_TYPE, aes.encrypt(gson.toJson(value).getBytes()));
} else {
return RequestBody.create(MEDIA_TYPE1, gson.toJson(value));
}
}
}
/**
* 自定义响应ResponseBody
*/
public class ResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private boolean isAes;
private Type type;
public ResponseBodyConverter(Type type, boolean isAes) {
this.isAes = isAes;
this.type = type;
}
/**
* @param value
* @return T
* @throws IOException
*/
@Override
public T convert(ResponseBody value) throws IOException {
try {
if (isAes) {////这里加上你自己的解密方法
byte[] b = value.bytes();
AES aes = new AES();
byte[] a = aes.decrypt(b);
String json = new String(a);
return new Gson().fromJson(json, type);
} else {
String json = value.string();
return new Gson().fromJson(json, type);
}
} finally {
value.close();
}
}
}
}
接下来我们就初始化retrofit:
/**
* 提供Retrofit
* Created by Administrator on 2017/9/5.
*/
public class RetrofitProvider {
private static final String BASE_URL = "";//写上你的baseurl
public static Retrofit create(Context context, boolean isAes) {//第二个参数是否加密
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(90, TimeUnit.SECONDS);
builder.connectTimeout(90, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {//打印请求日志
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(new GetCookiesInterceptor(context));//拦截器,用于保存cookie和添加统一求情头
return new Retrofit.Builder().baseUrl(BASE_URL)
.client(builder.build())
.addConverterFactory(MGsonConverterFactory.create(isAes))//加入刚刚自定义的转换器MGsonConverterFactory
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
public static Retrofit create(Context context) {//默认不加密
return create(context, false);
}
}
前期工作准备好了,我们就开始看看如何使用吧!
1.结合rejava使用,编写API :
public interface ApiService {
@POST("/user/getUser.action")
Observable<UserEntity> getUsers(@Body Map<String, String> map);
}
private void getUser() {
Retrofit retrofit = RetrofitProvider.create(this, true);
ApiService apiService = retrofit.create(ApiService.class);
Map<String, String> map = new HashMap<>();
map.put("userName", "userName");
map.put("password", "123456");
apiService.getUsers(map).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<UserEntity >() {
@Override
public void accept(UserEntity user) throws Exception {
Toast.makeText(MainActivity.this, "获取成功", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "获取失败", Toast.LENGTH_SHORT).show();
}
});
}
单独使用:
public interface ApiService {
@POST("/user/getUser.action")
Call<UserEntity > getUser(@Body Map<String, String> map);
}
private void getUser() {
Retrofit retrofit = RetrofitProvider.create(this, true);
ApiService apiService = retrofit.create(ApiService.class);
Map<String, String> map = new HashMap<String, String>();
map.put("userName", "username");
map.put("password", "123456");
Call<UserEntity > call = apiService.getUser(map);
call.enqueue(new Callback<UserEntity >() {
@Override
public void onResponse(Call<UserEntity > call, Response<UserEntity > response) {
L.d(response.body().toString());
}
@Override
public void onFailure(Call<UserEntity > call, Throwable t) {
}
});
}