Retrofit非成功状态码下response.body()返回null Postman可正常获取响应
问题原因
这是Retrofit的内置规则:只有当响应状态码属于 2xx(成功区间) 时,response.body() 才会被自动解析为你定义的泛型实体类RegistrasiResponse。非2xx的响应(比如你日志中的409状态码),响应内容不会走body()的解析逻辑,而是存放在response.errorBody()中,所以你直接读取response.body()必然得到null。
解决方法
修改你RemoteDataSource中onResponse回调的非成功分支逻辑,手动解析errorBody中的JSON内容即可:
override fun onResponse( call: Call<RegistrasiResponse>, response: Response<RegistrasiResponse> ) { val data = response.body() Log.d("RemoteDataSource0", "$data") if (response.isSuccessful) { result.postValue(data?.let { ApiResponse.Success(data) }) } else { // 非2xx响应时从errorBody取内容 val errorBodyContent = response.errorBody()?.string() val errorMsg = if (!errorBodyContent.isNullOrEmpty()) { // 手动解析JSON为RegistrasiResponse对象 val errorResponse = Gson().fromJson(errorBodyContent, RegistrasiResponse::class.java) errorResponse.message ?: "请求失败,无错误提示" } else { "请求失败,响应内容为空" } result.postValue(ApiResponse.Error(errorMsg)) } EspressoIdlingResource.decrement() }
注意事项
response.errorBody().string()只能调用1次,调用后对应流会被自动关闭,所以必须用临时变量存储内容后再处理- 如果你的项目中Retrofit已经自定义配置了Gson实例,建议复用该实例解析errorBody,避免序列化/反序列化规则不一致导致解析失败
- 不要忘记在
onResponse和onFailure回调中都调用EspressoIdlingResource.decrement(),避免IdlingResource计数异常
内容的提问来源于stack exchange,提问作者Mohammad Azri Khairuddin
相关产品推荐
相关产品推荐

