RxJava学習ノート2:RxJava+okHttpに基づくRest Cas登録実装
1.本来はRxJavaをサポートするRetrofit 2で実現しようとしたが、Retrofit 2の文書はほとんどなく、Cookieを取得できる、status code処理の方法が見つからなかったため、okHttpで実現した.先週から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:)
依存関係:
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
2.ST取得
3.Cookieの交換
統合
依存関係:
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.パッケージ取得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");
}
});
}