【问题标题】:Retrofit 2 request doesn't give me data改造 2 请求没有给我数据
【发布时间】:2019-10-26 16:03:06
【问题描述】:

我正在尝试通过 Retrofit 2 发送 GET 请求。

但是,请求没有做任何事情..

API 服务

package com.example.brews.network

import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.Deferred
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query

/*
    This is the sandbox base url (way less data than production environment)
    When deploying app -> use production base url
 */
private const val BASE_URL = "https://sandbox-api.brewerydb.com/v2/"

/**
 * Build the Moshi object that Retrofit will be using, making sure to add the Kotlin adapter for
 * full Kotlin compatibility.
 */
private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

/**
 * Use the Retrofit builder to build a retrofit object using a Moshi converter with our Moshi
 * object.
 */
private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .addCallAdapterFactory(CoroutineCallAdapterFactory())
    .baseUrl(BASE_URL)
    .build()

/**
 * A public interface that exposes the [getProperties] method
 */
interface BreweryApiService {
    /**
     * Returns a Coroutine [Deferred] [List] of [BeerProperty] which can be fetched with await() if
     * in a Coroutine scope.
     * The @GET annotation indicates that the "beers" endpoint will be requested with the GET
     * HTTP method
     */
    @GET("beers/")
    fun getProperties(@Query("?key") key: String):
    // The Coroutine Call Adapter allows us to return a Deferred, a Job with a result
            Deferred<List<BeerProperty>>

}

/**
 * A public Api object that exposes the lazy-initialized Retrofit service
 */
object BreweryApi {
    val retrofitService: BreweryApiService by lazy { retrofit.create(BreweryApiService::class.java) }
}

数据类

package com.example.brews.network

data class BeerProperty(
    val id: Int,
    val name: String
)

填满我的列表的方法

private fun getBeersProperties() {
    coroutineScope.launch {
        var getPropertiesDeferred =
            BreweryApi.retrofitService.getProperties("13e9caaf80adac04dce90ef55600d898")
        try {
            _status.value = BreweryApiStatus.LOADING
            val listResult = getPropertiesDeferred.await()
            _status.value = BreweryApiStatus.DONE
            _properties.value = listResult
        } catch (e: Exception) {
            _status.value = BreweryApiStatus.ERROR
            _properties.value = ArrayList()
        }
    }
}

链接检索到的 JSON

{ “当前页面”:1, “页数”:23, “总结果”:1109, “数据”: [ { “id”:“c4f2KE”, "name": "'Murican Pilsner", "nameDisplay": "'Murican Pilsner", “abv”:“5.5”, "glasswareId": 4, “styleId”:98, "isOrganic": "N", “已退休”:“N” }
] }

我需要检索的是“数据”中的“ID”和“名称”。但是,这是一个数组,我不知道如何通过改造来提取它..

【问题讨论】:

    标签: java android kotlin retrofit retrofit2


    【解决方案1】:

    您需要有一个 DAO 对象来从改造中获取 JSON 响应,然后解析 JSON 对象以获得您想要的结果。

    所以像这样创建一个 DAO 对象:-

    data class BeerResponse(
      val data: List<BeerProperty>?
    )
    

    并将您的服务方法更改为:-

    @GET("beers/")
    fun getProperties(@Query("?key") key: String):
    // The Coroutine Call Adapter allows us to return a Deferred, a Job with a result
            Deferred<BeerResponse>
    

    然后在您的 getBeerProperties 方法中,将其更改为:-

    private fun getBeersProperties() {
    coroutineScope.launch {
        var getPropertiesDeferred =
            BreweryApi.retrofitService.getProperties("13e9caaf80adac04dce90ef55600d898")
        try {
            _status.value = BreweryApiStatus.LOADING
            val listResult = getPropertiesDeferred.await()
            listResult.data?.let {
                _status.value = BreweryApiStatus.DONE
                _properties.value = it
            } ?: let {
                _status.value = BreweryApiStatus.ERROR
                _properties.value = ArrayList()
            }
        } catch (e: Exception) {
            _status.value = BreweryApiStatus.ERROR
            _properties.value = ArrayList()
        }
    }
    

    【讨论】:

      【解决方案2】:

      您对网络 API 的实现是错误的,应该改成这个

      data class BeerProperty(
          val id: Int,
          val name: String
      )
      
      data class Response(
        val data: List<BeerProperty>?
      )
      
      interface BreweryApiService {
          @GET("beers/")
          fun getProperties(@Query("?key") key: String):
                  Deferred<Response>
      }
      

      您还可以将页数、当前页和 ... 放入 Response 类中 此外,您可以在 android studio 中使用 JSON to kotlin 类插件来使这些数据类更快,错误更少,您还可以使用this 等网站查看更易读的漂亮格式的 JSON

      【讨论】:

        猜你喜欢
        • 2018-04-04
        • 2018-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-08
        • 1970-01-01
        相关资源
        最近更新 更多