执行多个RxJava调用并使用结果进行下一次调用

时间:2018-04-06 10:23:39

标签: android kotlin retrofit2 rx-java2

我正在尝试使用RxJava来解决这个问题。我有3个呼叫需要在彼此之后执行,使用最后一次呼叫的结果进行下一次呼叫。

为了简单起见,我在我的服务器上托管了3个文件:3个电话:

http://jimclermonts.nl/booky/step1user

http://jimclermonts.nl/booky/step2cookie

http://jimclermonts.nl/booky/step3token

这样做的最正确和最干净的方法是什么?

的build.gradle:

// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'

// reactive extensions
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

MainActivity:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val result = SomeWebService().getToken()
    if (result != null) {
        result.doOnComplete { 
            //how to get the token value?
        }
    }
}

SomeWebService

class SomeWebService {

    lateinit var apiService: ApiService
    var tokenResult: Observable<String>? = null

    fun getToken() : Observable<String>? {
        if (tokenResult == null) {
            apiService = ApiService.retrofit.create(ApiService::class.java)
            val body = step1ApiUserResponse()
            val cookie = step2CookieResponse(body.blockingSingle())
            val tokenResult = step3TokenResponse(cookie.blockingSingle())
            this.tokenResult = tokenResult
            tokenResult.doOnComplete {  }
    } else {
        tokenResult!!.doOnComplete {  }
    }
    return tokenResult
    }

    fun step1ApiUserResponse(): Observable<String> {
        return Observable.create {
            apiService.getStep1User()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSuccess { user ->
                        val body = user.getResponse()
                        if (body != null) {
                            it.onNext(body)
                        }
                    }
                    .doOnError {
                        it.printStackTrace()
                    }
        }
    }

    fun step2CookieResponse(body: String): Observable<String> {
        return Observable.create {
            apiService.getStep2Cookie(body)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSuccess { result ->
                        val bodyResult = result.body().toString()
                        it.onNext(bodyResult)
                    }
        }
    }

    fun step3TokenResponse(cookie: String): Observable<String> {
        return Observable.create {
            apiService.getStep3Token(cookie)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSuccess { result ->
                        val body = result.getToken()
                        if (body != null) {
                            it.onNext(body)
                        }
                    }
        }
    }
}

ApiService:

interface ApiService {

    @GET("/booky/step1user")
    fun getStep1User(): Single<UserResponse>

    @GET("/booky/step2cookie")
    fun getStep2Cookie(body: String): Single<Response>

    @GET("/booky/step3token")
    fun getStep3Token(@Header("Cookie") sessionId: String): Single<TokenResponse>

    companion object {

        val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
        val client = OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build()

        val retrofit = Retrofit.Builder()
                .baseUrl("http://jimclermonts.nl")
                .addConverterFactory(MoshiConverterFactory.create().asLenient())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build()
    }
}

TokenResponse:

class TokenResponse {

    @Json(name = "Token")
    private var token: String? = null

    fun getToken(): String? {
        return token
    }

    fun setToken(token: String) {
        this.token = token
    }
}

UserResponse:

class UserResponse {

    @Json(name = "Response")
    private var response: String? = null

    fun getResponse(): String? {
        return response
    }

    fun setResponse(response: String) {
        this.response = response
    }
}

1 个答案:

答案 0 :(得分:0)

MainActivity:

  val service = SomeWebService()

    service.getToken()
            .subscribe(
            { token ->
                Log.d("TOKEN", token)
            },
            {e ->
                Log.e("Token error", e.localizedMessage)
            }
    )

SomeWebService:

class SomeWebService {

    lateinit var apiService: ApiService
    var tokenResult: Observable<String>? = null

    fun getToken(): Observable<String> {
        apiService = ApiService.retrofit.create(ApiService::class.java)
        return step1ApiUserResponse()
                .flatMap { body ->
                    step2CookieResponse(body)
                            .flatMap { cookie ->
                                step3TokenResponse(cookie)
                            }

                }
    }

    fun step1ApiUserResponse(): Observable<String?> {
        return apiService.getStep1User()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map { user ->
                    Log.d("Step1", user.toString())
                    user.getResponse()
                }
                .toObservable()
    }

    fun step2CookieResponse(body: String): Observable<String?> {
        return apiService.getStep2Cookie(body)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map { result ->
                    result.getCookie()
                }
                .toObservable()
    }

    fun step3TokenResponse(cookie: String): Observable<String?> {
        return apiService.getStep3Token(cookie)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map { result ->
                    result.getToken()
                }
                .toObservable()
    }
}