Android 未为Http状态代码400调用Kotlin RxJava2 OneError

Android 未为Http状态代码400调用Kotlin RxJava2 OneError,android,kotlin,retrofit,rx-java2,okhttp3,Android,Kotlin,Retrofit,Rx Java2,Okhttp3,我正在开发的Android应用程序中使用RxJava2和OkHttp 对于这个应用程序,我使用的是Kotlin,并不是说它是Java还是Kotlin有什么区别 在我以前使用过的应用程序中,当服务器返回400错误代码时,将调用onError回调。但是,今天在进行此设置时,OneError回调仅在服务器关闭时触发,但即使对于400错误代码,也会调用onNext 下面是我的设置摘录 /** * Networking */ implementation "com.squareup.okhttp3:o

我正在开发的Android应用程序中使用RxJava2和OkHttp

对于这个应用程序,我使用的是Kotlin,并不是说它是Java还是Kotlin有什么区别

在我以前使用过的应用程序中,当服务器返回400错误代码时,将调用onError回调。但是,今天在进行此设置时,OneError回调仅在服务器关闭时触发,但即使对于400错误代码,也会调用
onNext

下面是我的设置摘录

/**
 * 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
    }
fun登录用户(用户名:String,密码:String):MutableLiveData{
if(username.isNotBlank()&&password.isNotBlank()){
subscriptions.addAll(remoteUserRepository
.getUser(UserDto(用户名、密码))
.subscribeBy(onNext={
saveUser(it.body())
saveAuthenticationToken(it.headers().get(“token”))
},onError={handleError(it)})
}
返回resultLiveData
}
private fun saveUser(用户:用户?){
用户?,让我来{
localUserRepository.saveUser(it)
resultLiveData.value=Result.SUCCESS
}
}
私有身份验证令牌(令牌:字符串?){
令牌?.let{localUserRepository.saveToken(it)}
}
覆盖趣味手柄错误(错误:可丢弃){
super.handleError(错误)
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
D/OkHttp:-->POSThttp://10.0.2.2:3000/login http/1.1
内容类型:application/json;字符集=UTF-8
D/OkHttp:内容长度:48
主持人:10.0.2.2:3000
连接:保持活力
接受编码:gzip
用户代理:okhttp/3.11.0
-->端柱

D/OkHttp:
onError
捕获由于执行任务或处理结果而发生的错误

在你的情况下,改装电话是可以的

您必须处理响应的结果:
在您的
onSuccess
中,检查响应是否
issusccessful
,然后继续前进

,结果表明所面临的行为是正确的,原因如下:

@POST("/login")
fun login(@Body userDto: UserDto): Observable<Response<User>>
@POST("/login")
fun login(@Body userDto: UserDto): Observable<User>

在我的情况下,这是不可行的,因为我需要访问响应头。

OneRor只针对错误调用。虽然4xx代表数据传输的不成功调用,但它本质上并不是错误的。您可以使用
Response#issusccessful()
@TimCastelijns在成功回调(onNext或其他)中区分成功调用和不成功调用。这里是如何完成的:另外,我记得在RxJava1中,还为400个状态码响应调用了onError。你知道这个行为是否改变了吗?正如你所看到的这个例子,你链接到的只是处理调用本身的错误,而不是传输数据的“错误”,但是他正在检查
if(e instanceof HttpException)
,这是传输错误时发生的,还是我弄错了?你可以自己检查一下。附加一个调试器,触发401响应,看看会发生什么