当实际有值时,响应正文返回 null

Posted

技术标签:

【中文标题】当实际有值时,响应正文返回 null【英文标题】:Response body return null when there's actually a value 【发布时间】:2022-01-03 11:23:47 【问题描述】:

我希望响应正文在状态代码不成功时返回一个值,因为当我在 Postman 上尝试它时,它实际上给了我一条消息或 JSON 数组的属性之一。但是,当我尝试将响应主体存储到变量中时,它总是返回 null。不知道为什么

这是ApiService

@POST("register")
    fun registerAkun(
        @Body registrasiAkun: RegistrasiBodyRequest
    ): Call<RegistrasiResponse>

这是RemoteDataSource里面的方法

override fun registrasiAkun(registrasiAkun: RegistrasiBodyRequest): LiveData<ApiResponse<RegistrasiResponse>> 
        val result = MutableLiveData<ApiResponse<RegistrasiResponse>>()
        result.postValue(ApiResponse.Loading)
        EspressoIdlingResource.increment()

        val client = apiService.registerAkun(registrasiAkun)
        client.enqueue(object : Callback<RegistrasiResponse> 
            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 
                    data?.let 
                        result.postValue(ApiResponse.Error(it.message.toString()))
                     ?: run 
                        Log.d("RemoteDataSource", "$data dan $response")
                    
                
            

            override fun onFailure(call: Call<RegistrasiResponse>, t: Throwable) 
                Log.d("RemoteDataSourceFailure", t.message.toString())
                result.postValue(ApiResponse.Error(t.message.toString()))
            
        )

        return result
    

型号:

data class RegistrasiResponse(

    @SerializedName("message")
    val message: String? = null,

    @SerializedName("customer")
    val customer: CustomerResponse? = null
)
data class CustomerResponse(
    @field:SerializedName("nama_customer")
    val namaCustomer: String?,

    @field:SerializedName("id_customer")
    val idCustomer: Int?,

    @field:SerializedName("email_customer")
    val emailCustomer: String?
)

这是日志

I/okhttp.OkHttpClient: --> POST MY_URL
I/okhttp.OkHttpClient: Content-Type: application/json; charset=UTF-8
I/okhttp.OkHttpClient: Content-Length: 84
I/okhttp.OkHttpClient: "email_customer":"tesaje@gmail.com","nama_customer":"tesdlu","password":"12345678"
I/okhttp.OkHttpClient: --> END POST (84-byte body)
I/okhttp.OkHttpClient: <-- 409 MY_URL (287ms)
I/okhttp.OkHttpClient: x-powered-by: php/7.4.25
I/okhttp.OkHttpClient: cache-control: no-cache, private
I/okhttp.OkHttpClient: content-type: application/json
I/okhttp.OkHttpClient: vary: Accept-Encoding
I/okhttp.OkHttpClient: date: Thu, 25 Nov 2021 06:26:48 GMT
I/okhttp.OkHttpClient: server: LiteSpeed
I/okhttp.OkHttpClient: alt-svc: quic=":443"; ma=2592000; v="43,46", h3-Q043=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-27=":443"; ma=2592000
I/okhttp.OkHttpClient: "message":"User Registration Failed!"
I/okhttp.OkHttpClient: <-- END HTTP (39-byte body)
D/RemoteDataSource0: null
D/RemoteDataSource: null dan Responseprotocol=h2, code=409, message=, url=MY_URL

这就是 I expect 或 these

只要响应成功,就会返回这个

RegistrasiResponse(message=Registrasi Sukses, customer=CustomerResponse(namaCustomer=aaaaaa, idCustomer=50, emailCustomer=aaaaa@mail.com))

Postman response success

【问题讨论】:

你能分享你的 POSTMAN 响应成功和失败吗?然后我们可以了解响应。 @a_local_nobody 我认为不是,因为它是 Firebase(?) @Nilesh 共享,失败的是在 I expectthese 啊,我的错,没检查,没关系:) 【参考方案1】:

对于案例!isSuccessful,您应该从errorBody() 而不是body() 获取正文。

编辑: 您可能需要一个对象来保存message。例如

data class ErrorResponse(
    val message: String? = null
)

onResponse() 内部看起来像这样

if (response.isSuccessful) 
    result.postValue(response.body()?.let  
        ApiResponse.Success(it)
    )
 else 
    response.errorBody()?.string()?.let 
        val error = Gson().fromJson(it, ErrorResponse::class.java)
        result.postValue(ApiResponse.Error(error.message.orEmpty()))
     ?: run 
        Log.d("RemoteDataSource", "$response.errorBody()?.string() dan $response")
    

【讨论】:

我想要的是获得I/okhttp.OkHttpClient: "message":"User Registration Failed!"。它的消息。我没有得到消息的价值,而是得到D/RemoteDataSource: okhttp3.ResponseBody$Companion$asResponseBody$1@b7f93cf 基于你的解决方案response.errorBody()?.let Log.d("RemoteDataSource", response.errorBody().toString()) result.postValue(ApiResponse.Error(it.toString())) 你实际上不能直接使用response.errorBody().toString()。您可能需要一个对象来使用它。我会更新答案 Terima kasih banyak ya mas! 啜饮,不客气

以上是关于当实际有值时,响应正文返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent empty() 函数在 $request->url 有值时返回 true

当字典中没有匹配的非空值时,返回null。

使用 Retrofit 的 API 响应为某些非 null 的参数返回 null

当 HTTP 请求返回状态 401 时,如何在 Java 中解析响应正文

Json 有值,但它返回 null/nill

为啥 Oracle Left Join 在应该有值的地方返回 null