Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 尝试向服务器发送邮件时获取java.util.NoSuchElementException。来自服务器的回答是204/success,但仍然引发异常_Android_Retrofit2 - Fatal编程技术网

Android 尝试向服务器发送邮件时获取java.util.NoSuchElementException。来自服务器的回答是204/success,但仍然引发异常

Android 尝试向服务器发送邮件时获取java.util.NoSuchElementException。来自服务器的回答是204/success,但仍然引发异常,android,retrofit2,Android,Retrofit2,我正在向我的服务器发送邮件。结果是204/成功代码,结果的正文为空。java.util.NoSuchElementException在服务器的结果之后立即引发。我的猜测是,这是因为响应不包含任何实体(Void),但我非常不确定 我的界面 @POST("register/") fun register(@Body phone: PhoneBody): Single<Void> 它永远不会进入subscribe lambda,它直接进入这个::句柄,它是

我正在向我的服务器发送邮件。结果是204/成功代码,结果的正文为空。java.util.NoSuchElementException在服务器的结果之后立即引发。我的猜测是,这是因为响应不包含任何实体(Void),但我非常不确定

我的界面

    @POST("register/")
    fun register(@Body phone: PhoneBody): Single<Void>
它永远不会进入subscribe lambda,它直接进入这个::句柄,它是

        if (t is ApiException) {
            viewState.showError(t.message)
        } else if (t is IOException) {
            viewState.showError("No internet connection")
        }

        if (BuildConfig.DEBUG) {
            t.printStackTrace()
        }
    }
D/OkHttp:-->POSThttps://.../register/
D/OkHttp:Content-Type:application/json
D/OkHttp:内容长度:24
D/OkHttp:{“电话”:“+79090000000”}
D/OkHttp:-->结束POST(24字节正文)

D/OkHttp:正如@commonware在对问题的评论中所说的,问题是我使用了Single(从ctrl+c ctrl+V的逻辑->更改返回模型),我将其更改为Completable,现在它可以工作了

参见

使用Completable是一种解决方法,但如果响应有时会携带数据,则可以使用
Single
将拦截器添加到okhttpclient。所有学分归
jgavazzisp
LouisCAD

拦截器

    class EmptyBodyInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())
        if (response.isSuccessful.not() || response.code().let { it != 204 && it != 205 }) {
            return response
        }

        if ((response.body()?.contentLength() ?: -1) > 0) {
            return response.newBuilder().code(200).build()
        }

        val emptyBody = ResponseBody.create(MediaType.get("application/json"), "{}")

        return response
                .newBuilder()
                .code(200)
                .body(emptyBody)
                .build()
    }
}
在OkHttpClient上使用

private val okHttpClient: OkHttpClient by lazy { OkHttpClient().newBuilder()
        .addInterceptor(EmptyBodyInterceptor()).build() }

private var retrofit : Retrofit = Retrofit.Builder().client(okHttpClient).build()

单曲
对科特林来说似乎很奇怪。也许可以尝试
Completable
。如果出于某种原因它必须是一个
单曲
,试试
单曲
@commonware哦,好吧,现在我觉得很愚蠢,因为它实际上解决了问题。我把单身改成了可完成的。改成单身也没用。也许你应该把它写下来作为答案!非常感谢。我建议你回答你自己的问题,说明我的建议对你的情况有效。
    class EmptyBodyInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())
        if (response.isSuccessful.not() || response.code().let { it != 204 && it != 205 }) {
            return response
        }

        if ((response.body()?.contentLength() ?: -1) > 0) {
            return response.newBuilder().code(200).build()
        }

        val emptyBody = ResponseBody.create(MediaType.get("application/json"), "{}")

        return response
                .newBuilder()
                .code(200)
                .body(emptyBody)
                .build()
    }
}
private val okHttpClient: OkHttpClient by lazy { OkHttpClient().newBuilder()
        .addInterceptor(EmptyBodyInterceptor()).build() }

private var retrofit : Retrofit = Retrofit.Builder().client(okHttpClient).build()