我正在将RxJava2与Retrofit和OkHttp一起用于正在开发的Android应用程序中。
对于此应用程序,我使用的是Kotlin,不是Java还是Kotlin都可以。
在我之前使用的以前的应用程序中,当服务器返回 400 错误代码时,将调用onError回调。但是,今天在进行此设置时,仅在例如服务器关闭但仅针对 400 错误代码调用onNext
时,才会触发onError回调。
下面是我的设置中的摘录
/**
* Networking
*/
implementation "com.squareup.okhttp3:okhttp:3.11.0"
implementation "com.squareup.okhttp3:logging-interceptor:3.11.0"
implementation "com.squareup.retrofit2:retrofit:2.4.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
/**
* Rx
*/
implementation "io.reactivex.rxjava2:rxandroid:2.0.2"
implementation "io.reactivex.rxjava2:rxkotlin:2.2.0"
这是dagger2模块的摘录,该模块实际上构建了改造对象
@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient,
gson: Gson,
@BaseUrl baseUrl: String): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
}
这是调用API的实际代码
fun loginUser(username: String, password: String): MutableLiveData<Result> {
if (username.isNotBlank() && password.isNotBlank()) {
subscriptions.addAll(remoteUserRepository
.getUser(UserDto(username, password))
.subscribeBy(onNext = {
saveUser(it.body())
saveAuthenticationToken(it.headers().get("token"))
}, onError = { handleError(it) }))
}
return resultLiveData
}
private fun saveUser(user: User?) {
user?.let {
localUserRepository.saveUser(it)
resultLiveData.value = Result.SUCCESS
}
}
private fun saveAuthenticationToken(token: String?) {
token?.let { localUserRepository.saveToken(it) }
}
override fun handleError(error: Throwable) {
super.handleError(error)
resultLiveData.value = Result.FAILURE
}
这是来自服务器的请求和响应的日志,清楚地表明服务器正在返回http代码401
D/OkHttp: --> POST http://10.0.2.2:3000/login http/1.1
Content-Type: application/json; charset=UTF-8
D/OkHttp: Content-Length: 48
Host: 10.0.2.2:3000
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.11.0
--> END POST
D/OkHttp: <-- 401 Unauthorized http://10.0.2.2:3000/login (20ms)
content-type: application/json; charset=utf-8
cache-control: no-cache
content-length: 94
Date: Mon, 13 Aug 2018 13:55:07 GMT
Connection: keep-alive
<-- END HTTP
即使服务器返回401错误,也不会调用handleError(error: Throwable)
回调。仅在服务器无法访问时调用。
我想念什么?
答案 0 :(得分:1)
onError
确实捕获了由于执行任务或处理结果而发生的错误。
如果您愿意,可以打电话给我们
您必须处理响应结果:
在您的onSuccess
中,检查是否响应isSuccessful
并继续
答案 1 :(得分:0)
事实证明,由于以下原因,面临的行为是正确的:
@POST("/login")
fun login(@Body userDto: UserDto): Observable<Response<User>>
如您所见,函数的返回类型为Observable<Response<User>>
更准确地为Response<User>
因此,无论http状态代码如何,只要收到响应,就会调用onNext
。无法收到响应时,只有onError
被调用。
因此,如果您想退回Response
,则需要使用@MaxAves建议的方法
如果您希望在服务器返回400错误代码时调用onError
,则需要修改该接口,使其类似于以下内容:
@POST("/login")
fun login(@Body userDto: UserDto): Observable<User>
在我来说,这是不可行的,因为我需要访问响应头。