skip to Main Content

By okhttp log I know I get response from remote server. But when I try to parse response I receive null! How to correct parse response from the server to get data?

My Data object:

@Parcelize
data class DataItem(

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

) : Parcelable

MY Api:

interface Api {

    @GET("v1/media/list/image")
    suspend fun getImage(): DataItem
}

My Retrofit object:

  private val httpClient = OkHttpClient
        .Builder()
        .protocols(listOf(Protocol.HTTP_1_1))
        .addInterceptor(BearerTokenInterceptor(TOKEN))
        .addInterceptor(logInterceptor())

    //get api by retrofit
    private val api: TVApi by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient.build())
            .build()
        retrofit.create(TVApi::class.java)
    }

    private fun logInterceptor() : HttpLoggingInterceptor {
        val interceptor = HttpLoggingInterceptor()
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)

        return interceptor
    }

My try to parse the response:

 private val scope = CoroutineScope(Dispatchers.IO)

    private fun getNetworkResponse() {

        scope.launch {
            try {
                Log.d(MY_TAG, "api: ${api.getVideo()}")

            } catch (e: IOException) {
                Log.e(MY_TAG, "IOException: $e")
            } catch (e: HttpException) {
                Log.e(MY_TAG, "HttpException: $e")
            }
        }
    }

OKhttp log:

{"code":200,"message":"Success","data":[{"name"....}

My Log:

api: DataItem(extension=null, size=null, name=null, url=null)

2

Answers


  1. Chosen as BEST ANSWER

    By mistake I called DataItem object instead VideoResponse or ImageResponse

    My JSON:

    {
        "code": 200,
        "message": "Success",
        "data": [
            {
                "name": "Welcome",
                "url": "https://...",
                "size": "27.34MB",
                "extension": "mp4"
            }
        ]
    }
    

    It parse to follow data classes:

    @Parcelize
    data class DataItem(
    
        @field:SerializedName("extension")
        val extension: String? = null,
    
        @field:SerializedName("size")
        val size: String? = null,
    
        @field:SerializedName("name")
        val name: String? = null,
    
        @field:SerializedName("url")
        val url: String? = null
    ) : Parcelable
    
    @Parcelize
    data class ImageResponse(
    
        @field:SerializedName("code")
        val code: Int? = null,
    
        @field:SerializedName("data")
        val data: List<DataItem?>? = null,
    
        @field:SerializedName("message")
        val message: String? = null
    ) : Parcelable
    
    @Parcelize
    data class VideoResponse(
    
        @field:SerializedName("code")
        val code: Int? = null,
    
        @field:SerializedName("data")
        val data: List<DataItem?>? = null,
    
        @field:SerializedName("message")
        val message: String? = null
    ) : Parcelable
    

  2. It looks like your data class does not match the JSON structure. Gson does not report missing or unknown properties, which is why this mismatch might not be obvious.

    Your JSON data suggests there should be an enclosing data class, let’s call it Response:

    data class Response(
        val code: Int,
        val message: String,
        val data: List<DataItem>,
    )
    

    And then the function in your Api interface should have that as return type:

    interface Api {
    
        @GET("v1/media/list/image")
        suspend fun getImage(): Response
    }
    

    (Also, please check the code in your question again. The Api interface has a function called getImage, but in your code below you call getVideo; and your log output shows that DataItem has additional properties such as extension, which are not shown in the code of your DataItem class above.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search