I am using retrofit2.6.2 for api call. LoggingInterceptor showing full response in logcat but retrofit response body return null. I didn't figure out where is my problem.
My json data schema is
{
"error":false,
"msg":"Banner Found",
"id":"9",
"activity":"VipPremium1",
"imageUrl":"https:\/\/1.bp.blogspot.com\/-Kh3RQlJH7Xw\/X-1mIPi7_HI\/AAAAAAAAFME\/Y2bCnU5odngcdDT83uC9QwUr7IGJdTDfACLcBGAsYHQ\/s2616\/COMPRESSED_IMG_1609393684674.jpg",
"actionUrl":"https:\/\/www.youtube.com\/watch?v=ukJX5ZgJec4",
"actionType":1,
"visible":true
}
Model Class BannerRes
data class BannerRes(
@SerializedName("actionType")
val actionType: Int?,
@SerializedName("actionUrl")
val actionUrl: String?,
@SerializedName("activity")
val activity: String?,
@SerializedName("error")
val error: Boolean?,
@SerializedName("id")
val id: String?,
@SerializedName("imageUrl")
val imageUrl: String?,
@SerializedName("msg")
val msg: String?,
@SerializedName("visible")
val visible: Boolean?
)
Api Interface
@GET("api/helper.getBanner.php")
suspend fun getBanner(
@Query("bannerName") bannerName: String,
): Response<BannerRes>
Api call done here
private fun loadPremiumBanner() {
Coroutines.main {
val res = viewModel.getBanner("VipPremium1")
Log.d("Response", res.body()!!.msg!!)
}
}
When I print response body using
Log.d("Response", Gson().toJson(res.body()))
It shows the the response in logcat, Logcat
{"error":false,"msg":"Banner Found","id":"9","activity":"VipPremium1","imageUrl":"https://1.bp.blogspot.com/-Kh3RQlJH7Xw/X-1mIPi7_HI/AAAAAAAAFME/Y2bCnU5odngcdDT83uC9QwUr7IGJdTDfACLcBGAsYHQ/s2616/COMPRESSED_IMG_1609393684674.jpg","actionUrl":"https://www.youtube.com/watch?v\u003dukJX5ZgJec4","actionType":1.0,"visible":true}
but when access res.body()!!.msg
It shows null.
Retrofit Setup
companion object {
@Volatile
private var myApiInstance: MyApi? = null
private val LOCK = Any()
operator fun invoke() = myApiInstance ?: synchronized(LOCK) {
myApiInstance ?: createClient().also {
myApiInstance = it
}
}
private fun createClient(): MyApi {
val AUTH: String = "Basic ${
Base64.encodeToString(
("${BuildConfig.USER_NAME}:${BuildConfig.USER_PASSWORD}").toByteArray(),
Base64.NO_WRAP
)
}"
val interceptor = run {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.apply {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
}
}
val okHttpClient: OkHttpClient = OkHttpClient.Builder()
.callTimeout(10,TimeUnit.SECONDS)
.addInterceptor(interceptor)
.addInterceptor { chain ->
val original: Request = chain.request()
val requestBuilder: Request.Builder = original.newBuilder()
.addHeader("Authorization", AUTH)
.method(original.method, original.body)
val request: Request = requestBuilder.build()
chain.proceed(request)
}
.build()
val gsonBuilder = GsonBuilder()
gsonBuilder.setLenient()
val gson = gsonBuilder.create()
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClient)
.build()
.create(MyApi::class.java)
}
}
CodePudding user response:
I think you can't use both Gson and Scalars Converter in Retrofit because retrofit confuse to wrap it.
Remove Scaler (I prefer Gson) and try again.
If not work then use GsonConverterFactory.create()
this.
CodePudding user response:
With Retrofit you can consume the response body only once. So the first call to body()
will return the response but further calls will not. You're consuming your body when you're logging it.