Rxjava2+retrofit2封装 post 固定json参数

需求:服务端要求请求方式为post,传递参数为json格式
在请求后台服务时,移动端又要每次携带固定参数
普通的@post 然后通过@Query设置参数 无法满足需求
经一番查询post Json需要通过okhttp中拦截器实现

   //post数据
 RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());

拦截器添加了返回结果输出

client.addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                //获得请求信息,
                Request originalRequest = chain.request();
                // 返回添加body的请求
                Request requests = setupRequestBody(originalRequest);
                log.i(requests.url());
                //记录请求耗时
                long startNs = System.nanoTime();
                okhttp3.Response response;
                try {
                    //发送请求,获得相应,
                    response = chain.proceed(requests);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
                long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
                //打印请求耗时
                log.i("耗时:" + tookMs + "ms");

                //获得返回的body,注意此处不要使用responseBody.string()获取返回数据,原因在于这个方法会消耗返回结果的数据(buffer)
                ResponseBody responseBody = response.body();

                //为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                //获得返回的数据
                Buffer buffer = source.buffer();
                //使用前clone()下,避免直接消耗
                log.i("response:" + buffer.clone().readString(Charset.forName("UTF-8")));
                return response;
            }
        });
private Request setupRequestBody(Request oldRequests) {
        JSONObject json = getBaseJson();
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
        log.i("requestBody-json", json.toString());
        //返回一个新的RequestBody
        return oldRequests.newBuilder()
                .url(oldRequests.url())
                .method(oldRequests.method(), body)
                .build();
    }

这里getBaseJson是后台服务要求json数据.
除了固定参数,有时json还需要添加其他参数
所以需要定义一个向BaseJson添加数据的接口

public MaRetrofit addJson(String key, String value) {
        try {
            getBaseJson().put(key, value);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return this;
    }

下面首先Retrofit类全部代码

public class MaRetrofit {
    LogUtils log = LogUtils.hLog();
    Retrofit retrofit;
    OkHttpClient.Builder client;
    JSONObject postJson;

    public MaRetrofit() {
        if (client == null) {
            client = new OkHttpClient.Builder();
        }
        addInterceptor();
    }

    public Retrofit create() {
        retrofit = new Retrofit.Builder()
                .client(client.build())
                .baseUrl(Constants.URL + "/")
                .addConverterFactory(GsonConverterFactory.create())
                //添加返回rx对象
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        return retrofit;
    }

    public UrlServiceInterface getUrlServiceInterface() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .client(client.build())
                    .baseUrl(Constants.URL + "/")
                    .addConverterFactory(GsonConverterFactory.create())
                     //添加返回rx对象
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        }
        return retrofit.create(UrlServiceInterface.class);
    }


    public MaRetrofit addJson(String key, String value) {
        try {
            getBaseJson().put(key, value);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return this;
    }

    private JSONObject getBaseJson() {
        if (postJson == null) {
            postJson = new JsonBean().getJson(MaApplication.getContext());
        }
        return postJson;
    }


    public Retrofit addInterceptor() {
        if (client == null) {
            return null;
        }
        client.addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                //获得请求信息,
                Request originalRequest = chain.request();
                // 返回添加body的请求
                Request requests = setupRequestBody(originalRequest);
                log.i(requests.url());
                //记录请求耗时
                long startNs = System.nanoTime();
                okhttp3.Response response;
                try {
                    //发送请求,获得相应,
                    response = chain.proceed(requests);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
                long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
                //打印请求耗时
                log.i("耗时:" + tookMs + "ms");

                //获得返回的body,注意此处不要使用responseBody.string()获取返回数据,原因在于这个方法会消耗返回结果的数据(buffer)
                ResponseBody responseBody = response.body();

                //为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                //获得返回的数据
                Buffer buffer = source.buffer();
                //使用前clone()下,避免直接消耗
                log.i("response:" + buffer.clone().readString(Charset.forName("UTF-8")));
                return response;
            }
        });
        return retrofit;
    }

    private Request setupRequestBody(Request oldRequests) {
        JSONObject json = getBaseJson();
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
        log.i("requestBody-json", json.toString());
        //返回一个新的RequestBody
        return oldRequests.newBuilder()
                .url(oldRequests.url())
                .method(oldRequests.method(), body)
                .build();
    }
}

UrlServiceInterface.class就是一些url请求方法名了
示例
由于参数都是又post json传递了所以这里goLogin就不需要在添加参数了

public interface UrlServiceInterface {
    String URL_LOGIN = "xxxx/xxxxx/valid_verify_code";
    String moblie = "mobile";
    String verifyCode = "verifyCode";
    /**
     * 登录
     * 添加参数 mobile
     * 添加参数 verifyCode
     */
    @POST(URL_LOGIN)
    Observable<BaseEntity<Bean>> goLogin();
    //如果不需要使用rxjava直接返回call对象即可
    @POST(URL_LOGIN)
    Call<BaseEntity<Bean>> goLoginCall();

    }
}

到这里retrofit2就简单封装完毕了
根据需要选择直接返回retrofit还是返回UrlServiceInterface对象

如果不使用rxjava的使用方式

  UrlServiceInterface loginService = new MaRetrofit()
                .addJson(UrlServiceInterface.moblie, tel)
                .addJson(UrlServiceInterface.verifyCode, code)
                .getUrlServiceInterface();
        Call<BaseEntity<Bean>> call =  loginService.goLoginCall();
        call.enqueue(new Callback<BaseEntity<Bean>>() {
            @Override
            public void onResponse(retrofit2.Call<BaseEntity<Bean>> call, Response<BaseEntity<Bean>> response) {
                //处理response返回对象
            }

            @Override
            public void onFailure(retrofit2.Call<BaseEntity<Bean>> call, Throwable t) {

            }
        });

BaseEntity.java

public class BaseEntity<T> implements Serializable {
    /**
     * code :
     * message :
     * resultData : {}
     * success :
     * token :
     */

    private String code;
    private String message;
    public T resultData;
    private boolean success;
    private String token;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }


    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

}

如果rxjava和retrofit结合,
先封装一个RxSchedulers

public class RxSchedulers {
    public static <T> ObservableTransformer<T, T> ioMain() {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());
            }
        };
    }
}

然后简单封装一个Observable对象

public abstract class BaseObserver<T> implements Observer<BaseEntity<T>> {
    private Context mContext;
    LogUtils log = LogUtils.hLog();
    private Disposable mDisposable;
    public BaseObserver(Context context) {
        mContext = context;
    }
    @Override
    public void onSubscribe(Disposable d) {
        mDisposable = d;
    }
    @Override
    public void onNext(BaseEntity<T> value) {
        //根据判断选择返回正确对象
        if (value.isSuccess()) {
            T t = value.resultData;
            if(t!=null){
                onHandleSuccess(t);
            }
        } else {
            onHandleError(value.getCode(), value.getMessage());
        }
        //有时需要返回的全部对象
        onHandle(value);
    }

    @Override
    public void onError(Throwable e) {
        log.d(" ", "error:" + e.toString());
        Toast.makeText(mContext, "网络异常,请稍后再试", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onComplete() {
    }

    public abstract void onHandleSuccess(T t);
    public void onHandle(BaseEntity<T> baseEntity){
    };
    public void onHandleError(String code, String message) {
        Toast.makeText(mContext, message + code, Toast.LENGTH_LONG).show();
    }
}

下面使用rxjava和retrofit结合使用网络请求

 UrlServiceInterface loginService = new MaRetrofit()
                .addJson(UrlServiceInterface.moblie, tel)
                .addJson(UrlServiceInterface.verifyCode, code)
                .getUrlServiceInterface();

        Observable<BaseEntity<Bean>> observable = loginService.goLogin();

            observable.compose(RxSchedulers.<BaseEntity<Bean>>ioMain())
                .subscribe(new BaseObserver<Bean>(this) {
                    @Override
                    public void onHandleSuccess(Bean bean) {
                        //正常数据返回
                    }
                   @Override
                   public void onHandle(BaseEntity<Bean> baseEntity) {
                          super.onHandle(baseEntity);
                          //根据需要使用BaseEntity
                    }
                });

gradle引用包列表

    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'io.reactivex.rxjava2:rxjava:2.1.0'
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'//转换器,请求结果转换成Model
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
    compile 'com.squareup.okhttp3:okhttp:3.6.0'

结合网上许多资源 ,然后根据自己需求封装,
如果对你有帮助
点个赞就行
github地址:https://github.com/hanjole/rxjava2retrofit2Succinct

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,072评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 又是一年中秋佳节,祝各位中秋节快乐。 今天我们来聊聊这个最近很火的网络请求库retrofit,在此基础上会延伸出一...
    涅槃1992阅读 7,784评论 13 133
  • 我猜,我爷爷奶奶,大抵从来不谈爱情这件事,恐怕年轻时,也不大曾谈起。 奶奶碎嘴,整天叨叨叨,急躁,性情中人。她内心...
    花花花无缺阅读 452评论 0 0
  • /etc/shadow文件 字段说明: 登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:...
    不步步不阅读 388评论 0 0