gson Retrofit2响应成功,响应正文中预期的对象列表为空

pieyvz9o  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(215)

首先,我想说的是,我是Android和Kotlin的新手,所以请耐心等待。一旦我说了这一点,我发现一些帖子与空的改型响应有关,这种响应可能是由错误的数据类引起的,通常是与真实的JSON中的变量名不同的变量名(通常,这个问题可以使用@SerializedName注解来修复)。
我使用其他端点连接到我的服务器,Android应用程序总是能正确地获得响应(例如,使用只有id字段的JSON的简单响应)。所有端点都已经使用Postman进行了验证,我的一个朋友在他的iOS应用程序中使用了相同的API,对他来说效果很好。
如何示例化改造:

请求制作器.kt

interface ApiService {
    @Headers("Content-Type: application/json")
    @POST("getUserToken/")
    suspend fun getUserToken(@Body userData: getUserTokenRequestData): Response<getUserTokenResponse>

    @Headers("Content-Type: application/json")
    @POST("registerNewUserWithTables/")
    suspend fun signupNewUser(@Body userData: singupUserTokenRequestData): Response<singupUserTokenResponse>

    @Headers("Content-Type: application/json")
    @POST("getProductsByUserId/")
    suspend fun getUserProductsById(@Body userData: getUserProductsByIdRequestData): Response<getUserProductsByIdResponse>
}

class RequestsMaker {

    // Receive the context of the activity to pr
    lateinit var data: String

    object ApiClient {
        private const val BASE_URL: String = "http://myserver.com/"

        private val gson : Gson by lazy {
            GsonBuilder().setLenient().create()
        }

        private val httpClient : OkHttpClient by lazy {
            OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .build()
        }

        private val retrofit : Retrofit by lazy {
            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(httpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build()
        }

        val apiService : ApiService by lazy{
            retrofit.create(ApiService::class.java)
        }
    }

    fun getRequestService():ApiService{
        return ApiClient.apiService
    }
}

定义的数据类(我手动创建,但由于失败,我还使用了“Kotlindata class File from JSON”Android Studio插件:

data class getUserProductsByIdRequestData(val id: Int)
data class getUserProductsByIdResponse(val products: productDataClass)

data class productDataClass(
    val locations: List<Location>
)

data class Location(
    val id: Int,
    val storageAreas: List<StorageArea>
)

data class StorageArea(
    val id: Int,
    val products: List<Product>
)

data class Product(
    val expirationDate: String,
    val id: Int,
    val name: String,
    val purchaseDate: String
)

来自服务器的预期JSON响应如下所示(通过使用Postman获得):

POST请求

http://myserver.com/getProductsByUserId/

{
    "id": 1
}

回应

{
    "locations": [
        {
            "id": 2,
            "storageAreas": [
                {
                    "id": 2,
                    "products": [
                        {
                            "id": 4,
                            "name": "Ipad Goloso",
                            "purchaseDate": "2021-06-01",
                            "expirationDate": "2021-05-25"
                        }
                    ]
                }
            ]
        }
    ]
}

我使用一个协程来调用它,我是这样使用它的:

private fun executeCall() {
    var retrofit = RequestsMaker().getRequestService()

    var request = getUserProductsByIdRequestData(id = 2)

    GlobalScope.launch(Dispatchers.Main) {
        try {
            var response = retrofit.getUserProductsById(request)

            if (response.isSuccessful && response.body() != null) {
                val content = response.body()
                if (content != null) {
                    Log.v("It worked message RESULT: ", content.toString())
                }
            }
            else {

                Log.w("Something went wrong with the request","lol")
                //Toast.makeText(context, "Something went wrong with the request", Toast.LENGTH_LONG).show()
            }

        } catch (e: Exception) {
            // This is the point to indicate the server is not responding
            Log.e("ExceptionError message", e.message.toString())
            Log.e("ExceptionError cause", e.cause.toString())
            Log.e("ExceptionError localizedMessage", e.localizedMessage.toString())
            Toast.makeText(applicationContext, "ERROR in the connection to the server", Toast.LENGTH_LONG).show()
        }
    }
}

但结果是检索到的产品始终为空... x1c 0d1x
任何想法都将是非常受欢迎的,因为我没有找到任何有用的信息,我如何可以解决这个问题后,一些天。
顺祝商祺。

zwghvu4y

zwghvu4y1#

你的改进函数返回一个getUserProductsByIdResponse。这个类在它的构造函数中需要一个瓦尔products。它没有得到--响应的顶层是一个名为“location”的数组。所以product字段(响应中唯一的字段)将被设置为null,其余的数据将被丢弃。
换句话说,响应数据结构与实际返回的数据不匹配。结果多了一层。可能是因为您为返回多个产品的单独请求编写了它,而这个请求只返回单个产品。

相关问题