在 Retrofit 中——获取 NULL 作为响应,但结果列在日志中

In Retrofit- Getting NULL as Response but the results are listed in logs

我尝试使用 Retrofit 从响应中获取数据,但我得到的是 空值 。 如果我敬酒响应它总是空但响应显示在日志中但它不是 加载到 Recyclerview

请帮我完成这个面试任务

我的回复Link: https://bikewise.org:443/api/v2/locations/markers?proximity=45.521728%2C-122.67326&proximity_square=100

我的实际反应

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "title": "Stolen 2021 Specialized Sirrus 2.0 (03-14-2021)",
        "description": "<img src='https://files.bikeindex.org/uploads/Pu/408280/large_IMG_5771.JPG'>  <a target=\"_blank\" href=\"https://bikeindex.org/bikes/1018433\">View details</a>",
        "occurred_at": "2021-03-14 22:31:13 -0500",
        "marker-size": "small",
        "marker-color": "#E74C3C",
        "id": 136982
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -122.65,
          45.51
        ]
      }
    }

ApiClient Class

object ApiClient {
    var BASE_URL: String = "https://bikewise.org:443/api/v2/locations/"
    val getClient: ApiInterfac
        get() {
            val gson = GsonBuilder().setLenient().create()
            val interceptor = HttpLoggingInterceptor()
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
            val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
            val retrofit = Retrofit.Builder().baseUrl(BASE_URL).client(client).addConverterFactory(GsonConverterFactory.create(gson)).build()
            return retrofit.create(ApiInterfac::class.java)
        }
}

ApiInterface class:

    @GET("markers?proximity=45.521728%2C-122.67326&proximity_square=100")
    fun getVideoList(): Call  < DataVideos >  
}

型号Class

data class DataVideos(
       // @SerializedName("type")
        var listme:List<Videos>,
        @SerializedName("title")
        var title:String,
        @SerializedName("description")
        var description: String)

下面是来自 var listme:List 的视频 Class

class Videos {

    @SerializedName("title")
    val title: String? = null
    @SerializedName("description")
    val description: String? = null
}

我的数据变得有趣

private fun getDat1a() {
        Log.d(TAG, "GetDataFun")
        val call: Call  < DataVideos > = ApiClient .getClient.getVideoList()
        call.enqueue(object: Callback  < DataVideos > {
            override fun onResponse(call: Call  < DataVideos > ? , response : Response  < DataVideos > ? ) {
                if(response!!.isSuccessful){
                    Toast.makeText(activity?.applicationContext!!,"Data:"+response!!.body()!!.listme,Toast.LENGTH_LONG).show()

                    val rst=response!!.body()
                    progerssProgressDialog.dismiss()
                    dataList.addAll(listOf(rst!!))
                    recyclerView.adapter!!.notifyDataSetChanged()
                }
            }
            override fun onFailure(call: Call  < DataVideos> ? , t : Throwable ? ) {
                progerssProgressDialog.dismiss()
                Log.d(TAG, "Failes"+t)
            }
        })
    }

I'm getting null in Toast as well in recyclerview but in logs i can find the data

我的日志可以显示输出

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"title":"Stolen 2021 Specialized Sirrus 2.0 (03-14-2021)","description":"\u003cimg src='https://files.bikeindex.org/uploads/Pu/408280/large_IMG_5771.JPG'\u003e  \u003ca target=\"_blank\" href=\"https://bikeindex.org/bikes/1018433\"\u003eView details\u003c/a\u003e","occurred_at":"2021-03-14 22:31:13 -0500","marker-size":"small","marker-color":"#E74C3C","id":136982},"geometry":{"type":"Point","coordinates":[-122.65,45.51]}},{"type":"Feature","properties":{"title":"Stolen 2018 Surly Straggler (01-13-2021)","description":"\u003cimg src='https://files.bikeindex.org/uploads/Pu/144946/large_IMG_4383.jpg'\u003e Break in to my garage. \u003ca target=\"_blank\" href=\"https://bikeindex.org/bikes/516282\"\u003eView details\u003c/a\u003e","occurred_at":"2021-01-13 05:00:00 -0600","marker-size":"small","marker-color":"#EE8276","id":134325},"geometry":{"type":"Point","coordinates":[-122.69,45.59]}}]}
2021-03-18 09:26:45.027 7776-8035/com.lab.optisol I/okhttp.OkHttpClient: <-- END HTTP (51772-byte body)

将此模型用于响应

fun getVideoList(): Call<YourResponse>   


data class YourResponse(
val type: String? = null,
val features: ArrayList<Features>? = null
)

data class Features(
val type: String? = null,
val properties: Properties? = null,
val geometry:Geometry?=null
)

class Properties(
@SerializedName("title")
@Expose
val title: String? = null,
@SerializedName("description")
@Expose
val description: String? = null,
@SerializedName("occurred_at")
@Expose
val occurred_at: String? = null,
@SerializedName("marker-size")
@Expose
val marker_size: String? = null,
@SerializedName("marker-color")
@Expose
val marker_color: String? = null,
@SerializedName("id")
@Expose
val id: Int? = null

)

data class Geometry(
val type:String?=null,
val coordinates:ArrayList<Double>?=null
)

您的 DataVideo class 不适合反序列化为 JSON。这些 classes 没有所需的序列化密钥。

使用这些 classes

data class Response(
    @SerializedName("features")
    val features: List<Feature>?,
    @SerializedName("type")
    val type: String?
)

data class Feature(
    @SerializedName("geometry")
    val geometry: Geometry?,
    @SerializedName("properties")
    val properties: Properties?,
    @SerializedName("type")
    val type: String?
)

data class Geometry(
    @SerializedName("coordinates")
    val coordinates: List<Double>?,
    @SerializedName("type")
    val type: String?
)

data class Properties(
    @SerializedName("description")
    val description: String?,
    @SerializedName("id")
    val id: Int?,
    @SerializedName("marker-color")
    val markerColor: String?,
    @SerializedName("marker-size")
    val markerSize: String?,
    @SerializedName("occurred_at")
    val occurredAt: String?,
    @SerializedName("title")
    val title: String?
)

要使用 JSON 生成数据 classes,您可以使用 JsonToKotlinClass Android Studio 插件

要反序列化,可以将其视为键值对,键是@serializedName 注释中提供的名称,值是您在其下方提供的数据字段中提供的值。

现在将其与您创建的模型进行比较。

  1. 首先,您没有为 listme 变量提供任何 @serializedName 注释,它如何知道要在该变量上序列化哪个键的值它应该具有 @serializedName("features") 注释。
  2. 在“features”键上方的 json 中,我们有键“type”,其值为字符串,因此我们需要另一个变量作为字符串,@serializedName 类型。
  3. 现在让我们看看您的视频模型 class 其中功能内的值 -> 列表 我们没有任何东西可以序列化模型中 json 中的键“类型”和“属性”,因此使用与 json 响应中相同的键创建适当的模型和变量,正如@Amit pandey[ 回答的那样=18=]

创建合适的模型class 你可以下载插件 Json 到 Kotlin class 当创建一个新的 class 时,单击 alt insert 您将获得将 json 转换为 kotlin class 的选项。 在那里你可以 post 你的 json 响应和你的模型 class 将被创建。