RxJava学习笔记2:基于RxJava+okHttp的Rest Cas登录实现
来源:互联网 发布:经传软件官网 编辑:程序博客网 时间:2024/05/04 20:40
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
- 以用户名和密码访问CAS Server获取 TGT
- 用1返回的TGT和约定好的服务端Service地址访问CAS Server,获取ST
- 用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 1
- RxJava学习笔记2:基于RxJava+okHttp的Rest Cas登录实现
- Retrofit2+RxJava+Okhttp学习笔记
- Retrofit+RxJava+Okhttp简单实现登录注册
- 基于Rxjava+Retrofit+Okhttp的webservices访问
- RxJava的学习笔记
- RxJava学习笔记2
- Rxjava+Retrofit+okhttp+mvp实现
- 基于Rxjava+Retrofit+Okhttp+LeanCloud的完整项目(段子手),供大家学习与交流
- 基于OkHttp和RxJava封装的Socket长连接开源库
- RxJava学习笔记1--RxJava原理和简单实现
- RXJava学习笔记(2)
- 使用rxjava,retrofit,okhttp实现mvp模式的数据解析
- rxjava+retrofit+okhttp实现流行的网络请求
- 基于RxJava、RxAndroid的EventBus实现
- [Android]基于RxJava、RxAndroid的EventBus实现
- 基于RxJava实现的MVP实例
- 基于RxJava的RxBus
- RxJava学习笔记
- spring+mybatis管理多个数据源(非分布式事务)
- Python学习笔记(一):最基本的HelloWorld
- openwrt-drivers-各文件之前联系
- C#程序 无法向会话状态服务器发出会话状态请求
- Linux C编程----2(makefile)
- RxJava学习笔记2:基于RxJava+okHttp的Rest Cas登录实现
- 支持c++11-gcc4.8的安装与升级
- android 查看应用签名
- intellij idea output 乱码 记录
- 安卓5.0 Material Design设计简单的一个使用特效
- java类加载器
- Java字节序转换
- linux常用命令
- poj--2083--Fractal(dfs)