RxJava2和Retrofit Http请求的封装
这是我第一次写博客,读者勿怪。
最近在使用RxJava2和Retrofit 的时候,想对RxJava2和Retrofit 进行封装,做成一个通用型的工具类,最终就写了这样一个工具类。
导包
compile ‘com.squareup.okhttp3:okhttp:3.6.0’
compile ‘com.squareup.okio:okio:1.11.0’
compile ‘com.google.code.gson:gson:2.8.0’
compile “io.reactivex.rxjava2:rxjava:2.x.y”
compile ‘io.reactivex.rxjava2:rxandroid:2.0.1’
compile ‘com.squareup.retrofit2:retrofit:2.1.0’
compile ‘com.squareup.retrofit2:converter-gson:2.1.0’
compile ‘com.squareup.retrofit2:converter-scalars:2.1.0’
compile ‘com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0’post和get的接口方法
post方法,post的json的字符串(RequestBody是有json(String)生成的);
get方法,放发内需要一个map对象,map的键值对,将会生成get方法后面带的参数。interface PostOrGet{ @Headers({"Content-Type: application/json","Accept: application/json"}) // @POST("{method}") @POST Observable<String> postJson( // @Path("method") String method, @Url String url, @Body RequestBody body ); @Headers({"Content-Type: application/json","Accept: application/json"}) @GET Observable<String> get( @Url String url, @QueryMap Map<String, Object> options ); }
RequestBody生成
本段代买需要传入map对象,用来生成json,做重要的“RequestBody.create(MediaType.parse(“application/json; encoding=utf-8”),string.toString());”是用来生的RequestBody对象。/** * 通过map对象转换成RequestBody,因项目有特殊需求,这里判断是否要加"[]" * @param map * @param isAray ture在参数两端添加[]"[{a:a,b:b}]",flase 不在参数两段添加[]"{a:a,b:b}" * @return */ public static RequestBody map2ResquestBody(Map<String,Object> map,boolean isAray){ Gson gson = new GsonBuilder() .setPrettyPrinting() .disableHtmlEscaping() .enableComplexMapKeySerialization() .create(); String parameters = gson.toJson(map); StringBuffer string=new StringBuffer(); if (isAray){ string.append("["); string.append(parameters); string.append("]"); }else { string.append(parameters); } RequestBody body = RequestBody.create(MediaType.parse("application/json; encoding=utf-8"),string.toString()); return body; }
- post请求
Retrofit retrofit=new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create()) //此转换器可将response转为string
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//rxjava2适配
.baseUrl(baseUrl)
.build();
这段是生成Retrofit对象;
PostOrGet post=retrofit.create(PostOrGet.class);
生成一个PostOrGet的实例;
post.postJson(url,body)
.subscribeOn(Schedulers.newThread())//在子线程中执行数据请求
.observeOn(Schedulers.io())//标记子线程
.doOnNext(onNextAtIOThread)//返回成功在子线程中执行
.observeOn(AndroidSchedulers.mainThread())//在主线程中执行
.subscribe(onNext, onError,onComplete);//分别在主线程中执行成功,失败,完成方法
发送数据,并在主线程和子线程分别回调方法
/**
* RxJavaAndRetrofit httpPost请求
* @param url 基础的Url,必须以"/"结尾,否则报错
* @param method baseUrl后面的参数
* @param body post参数
* @param onNext 请求成功后在执行
* @param onError 请求失败后执行
* @param onComplete
*/
public static void doPost(String baseUrl, final String method, RequestBody body, Consumer<? super String> onNextAtIOThread, Consumer<? super String> onNext, Consumer<? super Throwable> onError,
Action onComplete){
Retrofit retrofit=new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create()) //此转换器可将response转为string
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//rxjava2适配
.baseUrl(baseUrl)
.build();
PostOrGet post=retrofit.create(PostOrGet.class);
post.postJson(method,body)
.subscribeOn(Schedulers.newThread())//在子线程中执行数据请求
.observeOn(Schedulers.io())//标记子线程
.doOnNext(onNextAtIOThread)//返回成功在子线程中执行
.observeOn(AndroidSchedulers.mainThread())//在主线程中执行
.subscribe(onNext, onError,onComplete);//分别在主线程中执行成功,失败,完成方法
}
- 发送get请求
get请求和post请求内容差不多这里不赘述。
public static void doGet(String baseUrl, final String method,Map options, Consumer<? super String> onNextAtIOThread, Consumer<? super String> onNext, Consumer<? super Throwable> onError,
Action onComplete){
Retrofit retrofit=new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create()) //此转换器可将response转为string
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//rxjava2适配
.baseUrl(baseUrl)
.build();
PostOrGet get=retrofit.create(PostOrGet.class);
get.get(url,options)
.subscribeOn(Schedulers.newThread())//在子线程中执行数据请求
.observeOn(Schedulers.io())//标记子线程
.doOnNext(onNextAtIOThread)//返回成功在子线程中执行
.observeOn(AndroidSchedulers.mainThread())//在主线程中执行
.subscribe(onNext, onError,onComplete);//分别在主线程中执行成功,失败,完成方法
}
- 调用方法
get请求:
Map map=new HashMap();
map.put("key", KEY);
map.put("page",page);
map.put("pagesize",pagesize);
RxJava2AndRetrofitUtils.doGet(IMAGEBASEURL, url, map, new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i("TAG","IO线程调用"+s);
}
}, new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i("TAG","UI线程调用"+s);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.i("TAG","错误时调用");
throwable.printStackTrace();
}
}, new Action() {
@Override
public void run() throws Exception {
Log.i("TAG","方法执行完成后调用");
}
});
post请求:
String baseurl="http://114.114.114.114:13008/abc.services.web/abc.service.api/";
String url="com.abc.service.app.login";
Map<String, Object> map=new HashMap<>();
map.put("id", "222f9975-d439-4acc-afd7-d86ac244020b");
map.put("input", "13123456789");
map.put("customer_pwd","123456");
map.put("last_login_os","ANDROID");
map.put("fileds","");
map.put("push_client_id","noID");
RequestBody body= RxJava2AndRetrofitUtils.map2ResquestBody(map,true);
RxJava2AndRetrofitUtils.doPost(baseurl, url, body, new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("TAG", s + "=======iothread======"+(Thread.currentThread() == Looper.getMainLooper().getThread()));
}
}, new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("TAG", s + "=======mainthread======" + (Thread.currentThread() == Looper.getMainLooper().getThread()));
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
throwable.printStackTrace();
}
}, new Action() {
@Override
public void run() throws Exception {
Log.i("TAG","方法执行完成后调用");
}
});
- 配置ssl证书
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
Retrofit retrofit=new Retrofit.Builder()
.client(new OkHttpClient().newBuilder().sslSocketFactory(sslContext.getSocketFactory()) .hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}).build())
.build();
如果觉得以上代码麻烦,引用张鸿洋okhttp-utils的包
HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
Retrofit retrofit=new Retrofit.Builder()
.client(new OkHttpClient().newBuilder().sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager).build())
.build();
以上是引用张鸿洋okhttp-utils工具类的代码“https://github.com/square/okhttp”,感谢鸿洋大神。
- 注意事项
封装的方法无论是get请求还是post请求,这里都要求传入baseurl和一个method,baseurl和method将会组合成请求地址,需要注意的是baseurl必须是以“/”结尾的地址比如“http://114.114.114.114:13008/abc.services.web/abc.service.api/”,method参数不能含有“/”,所以建议baseurl以请求地址最后一个“/”结尾,而method是最后一个“/”后面的地址。
以下是引用“http://blog.csdn.net/jdsjlzx/article/details/51588605”的分析:
path 是绝对路径的形式:
path = “/apath”,baseUrl = “http://host:port/a/b”
Url = “http://host:port/apath”path 是相对路径,baseUrl 是目录形式:
path = “apath”,baseUrl = “http://host:port/a/b/”
Url = “http://host:port/a/b/apath”path 是相对路径,baseUrl 是文件形式:
path = “apath”,baseUrl = “http://host:port/a/b”
Url = “http://host:port/a/apath”path 是完整的 Url:
path = “http://host:port/aa/apath“,baseUrl = “http://host:port/a/b”
Url = “http://host:port/aa/apath”
工具类下载地址“http://download.csdn.net/detail/weiyouyinzhen/9839520”