Android 尝试向服务器发送邮件时获取java.util.NoSuchElementException。来自服务器的回答是204/success,但仍然引发异常
我正在向我的服务器发送邮件。结果是204/成功代码,结果的正文为空。java.util.NoSuchElementException在服务器的结果之后立即引发。我的猜测是,这是因为响应不包含任何实体(Void),但我非常不确定 我的界面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,它直接进入这个::句柄,它是
@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()