如何从 JSON 中解析特定的键,并使用 Retrofit 将其映射到一个类?

huangapple go评论64阅读模式
英文:

How can I parse a specific key from JSON and map it to a class using Retrofit?

问题

我是新手使用Retrofit,我尝试从API获取JSON并在我的RecyclerView中显示它。但问题是我获取的JSON有两个键,分别是resultoffers,如下所示。

我想要的是offers键内的值,并将其映射到一个名为Offers的类,该类如下所示:

但似乎没有方法可以做到这一点,而名为result的键正在创建问题。

我创建了一个对象,

object DealsNetwork {
    fun getRetrofitClient (): Retrofit {
        val gson = GsonBuilder ().setLenient ().create ()
        return Retrofit.Builder ()
            .baseUrl ("https://feed.linkmydeals.com/")
            .addConverterFactory (GsonConverterFactory.create (gson))
            .build ()
    }
}

一个服务,

interface DealsService {
    @GET("getOffers/?API_KEY=$api_key&incremental=1&format=json")
    suspend fun getOffers (): List<Offers>
}

最后,在我的Fragment中调用它,

        val dealsService = DealsNetwork.getRetrofitClient ().create (DealsService::class.java)


        CoroutineScope (Dispatchers.IO).launch {
            // 获取优惠列表
            val offers = dealsService.getOffers ()

            // 在主线程上处理结果
            withContext (Dispatchers.Main) {
                val rvDealsAdapter = DealsListRecyclerAdapter(deals, dealsViewModel)

                binding.rvDealsList.layoutManager = layoutManager
                binding.rvDealsList.adapter = rvDealsAdapter
            }

但这似乎不起作用,非常感谢任何帮助。

英文:

I am new to Retrofit and I am trying to fetch a JSON from an API and display it in my RecylerView. But the problem is the JSON I fetched has two keys, namely result and offers as shown below.

{"result":true,"offers":[{"lmd_id":"1285747","store":"box8.in","merchant_homepage":"https:\/\/box8.in\/","offer_text":"Free Chocolava Cake on All Orders","offer_value":"Free","title":"Free Chocolava Cake","description":"This voucher is applicable on All Orders (On minimum order of ₹450)","code":"","terms_and_conditions":"","categories":"Food and Beverages,Fast Food","category_array":{"Food and Beverages":["Fast Food"]},"featured":"No","publisher_exclusive":"N","url":"https:\/\/box8.in\/offers","smartLink":"https:\/\/smartlink.linkmydeals.com\/?account_id=18950&network=&url=https%3A%2F%2Fbox8.in%2Foffers","image_url":"","type":"Deal","offer":"Freebie","status":"new","start_date":"2023-01-11","end_date":"2023-06-27"}]}

What I want is value inside offers key, and map it to a class called Offers that looks like this:

data class Offers (
    val lmd_id: Int,
    val store: String?,
    val merchant_homepage: String?,
    val long_offer: String?,
    val title: String?,
    val description: String?,
    val code: String?,
    val terms_and_conditions: String?,
    val categories: String?,
    val featured: String?,
    val publisher_exclusive: String?,
    val url: String?,
    val smartlink: String?,
    val image_url: String?,
    val type: String?,
    val offer: String?,
    val offer_value: String?,
    val status: String?,
    val start_date: String?,
    val end_date: String?
)

But it doesn't seem there is a way to do that and the key called result is creating a problem.

I created an object,

object DealsNetwork {
    fun getRetrofitClient (): Retrofit {
        val gson = GsonBuilder ().setLenient ().create ()
        return Retrofit.Builder ()
            .baseUrl ("https://feed.linkmydeals.com/")
            .addConverterFactory (GsonConverterFactory.create (gson))
            .build ()
    }
}

A service,

interface DealsService {
    @GET("getOffers/?API_KEY=$api_key&incremental=1&format=json")
    suspend fun getOffers (): List<Offers>
}

And finally I called it in my Fragment,

        val dealsService = DealsNetwork.getRetrofitClient ().create (DealsService::class.java)


        CoroutineScope (Dispatchers.IO).launch {
            // Get list of offers
            val offers = dealsService.getOffers ()

            // Do something with the results on the main thread
            withContext (Dispatchers.Main) {
                val rvDealsAdapter = DealsListRecyclerAdapter(deals, dealsViewModel)

                binding.rvDealsList.layoutManager = layoutManager
                binding.rvDealsList.adapter = rvDealsAdapter
            }

But this doesn't seem to work, any help is highly appreciated.

答案1

得分: 0

你必须创建一个与你的API响应匹配的数据类。从你的响应中,我可以看到它是一个包含你想要提取的列表的JSON对象。你应该按照以下方式创建你的Response数据类:

data class Response(
    result: Boolean,
    offers: List<Offers>
)

这里,result 变量是可选的。然后在你的Retrofit API中使用这个 Response 数据类:

interface DealsService {
    @GET("getOffers/?API_KEY=$api_key&incremental=1&format=json")
    suspend fun getOffers (): Response
}

希望对你有所帮助!

英文:

You must create a data class that matches your API response. From your response, I can see that it's a JSON object containing the list you want to extract. You should create your Response data class as follows:

data class Response(
    result: Boolean,
    offers: List&lt;Offers&gt;
)

Here, the result variable is optional. Then use this Response data class in your Retrofit API:

interface DealsService {
    @GET(&quot;getOffers/?API_KEY=$api_key&amp;incremental=1&amp;format=json&quot;)
    suspend fun getOffers (): Response
}

Hope it helps!

huangapple
  • 本文由 发表于 2023年6月26日 01:37:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551676.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定