RxJava学习笔记2:基于RxJava+okHttp的Rest Cas登录实现

1.本来打算用已经对RxJava提供支持的Retrofit2实现,但Retrofit2的文档基本没有,没有找到可以获取Cookie、对status code处理的方法,所以还是用okHttp进行了实现
2.上周开始学习RxJava,是想解决多个网络请求嵌套访问的问题,CAS算是比较典型的多个同步请求后才能获取实际需要的内容。
3.代码中用到了”如何用okHttp进行Cookie的自动管理”,App这边对应Cas Server,服务A,服务B,这样至少要处理3个域名下的Cookie,自动管理是不能少的。代码来自http://stackoverflow.com/questions/25461792/persistent-cookie-store-using-okhttp-2-on-android
4.这次App实现决定采用了MVP模式,一个人做的好处就是可以很快的实现的自己的想法,当时觉得太麻烦了,那么多接口,重用可能性很小……这次登录请求由原来的基于Volley的普通请求改成现在的代码,幸亏用了MVP:)

依赖:

    compile 'com.squareup.okhttp:okhttp:2.6.0'
    compile 'com.squareup.okhttp:okhttp-urlconnection:2.6.0'
    compile 'io.reactivex:rxjava:1.1.0'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.google.code.gson:gson:2.5'
    compile 'com.jakewharton.timber:timber:4.1.0'

CAS的Rest接口:
http://jasig.github.io/cas/4.1.x/protocol/REST-Protocol.html

  1. 以用户名和密码访问CAS Server获取 TGT
  2. 用1返回的TGT和约定好的服务端Service地址访问CAS Server,获取ST
  3. 用ST请求Service地址,获取Cookie

1.封装获取TGT请求返回Observable

    public static Observable<String> getTGT(final String account, final String password) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(final Subscriber<? super String> subscriber) {
                try {
                    String tgtPath = casServer + "/v1/tickets";
                    FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
                    formEncodingBuilder.add("username", account);
                    formEncodingBuilder.add("password", password);
                    RequestBody formBody = formEncodingBuilder.build();

                    Request request = new Request.Builder()
                            .url(tgtPath)
                            .post(formBody)
                            .build();
                    Response response = mOkHttpClient.newCall(request).execute();
                    int code = response.code();
                    if (201 == code) {
                        String location = response.header("Location");
                        String tgt = location.substring(location.lastIndexOf("/") + 1);
                        subscriber.onNext(tgt);
                    } else {
                        System.out.println(code);
                        System.out.println(response.body().string());
                        subscriber.onError(new Exception("error"));
                    }
                } catch (Exception e) {
                    subscriber.onError(e);
                }
            }
        });
    }

2.获取ST

    public static Observable<String> getST(final String tgt, final String service) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(final Subscriber<? super String> subscriber) {
                try {
                    String stPath = casServer + "/v1/tickets/" + tgt; // POST /cas/v1/tickets/{TGT id} HTTP/1.0

                    FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
                    formEncodingBuilder.add("service", service);
                    RequestBody formBody = formEncodingBuilder.build();

                    Request request = new Request.Builder()
                            .url(stPath)
                            .post(formBody)
                            .build();

                    Response response = mOkHttpClient.newCall(request).execute();
                    if (!response.isSuccessful()) {
                        throw new IOException("Unexpected code " + response);
                    }
                    String st = response.body().string();
                    subscriber.onNext(st);
                    subscriber.onCompleted();

                } catch (IOException e) {
                    subscriber.onError(e);
                }
            }
        });
    }

3.换取Cookie

    public static Observable< List<String>> getCookie(final String st, final String service){
        return Observable.create(new Observable.OnSubscribe< List<String>>() {
            @Override
            public void call(Subscriber<? super  List<String>> subscriber) {
                try {
                    String cookiePath = service + "?" + "ticket=" + st;
                    Request request = new Request.Builder()
                            .url(cookiePath)
                            .build();
                    Response response = mOkHttpClient.newCall(request).execute();
                    if (!response.isSuccessful()) {
                        throw new IOException("Unexpected code " + response);
                    }
                    List<String> list = response.headers("Set-Cookie");
                    subscriber.onNext(list);
                    subscriber.onCompleted();
                }catch (Exception e){
                    e.printStackTrace();
                    subscriber.onError(e);
                }
            }
        });
    }

整合

    public void login(final String account, final String password, final String service) {
        getTGT(account, password)
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String tgt) {
                        return getST(tgt, service);
                    }
                })
                .flatMap(new Func1<String, Observable<List<String>>>() {
                    @Override
                    public Observable<List<String>> call(String st) {
                        return getCookie(st, service);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<String>>() {
                    @Override
                    public void onCompleted() {
                       Timber.e("onCompleted");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Toast.makeText(LoginActivity.this, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
                        Timber.e("onError");
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(List<String> s) {
                        Toast.makeText(LoginActivity.this, s.toArray().toString(), Toast.LENGTH_SHORT).show();
                        Timber.e("onNext");
                    }
                });
    }
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值