即使模型正确,来自 API 的响应也不会映射到对象

Posted

技术标签:

【中文标题】即使模型正确,来自 API 的响应也不会映射到对象【英文标题】:Responses from the API are not mapped to the object even when the models are correct 【发布时间】:2021-06-03 20:03:47 【问题描述】:

我正在使用改造来发出这样的 GET 请求:

@GET("auth/facebook")
    fun facebookSignUp(
        @Query("access_token") access_token: String
    ): Observable<FacebookReturn>

然后我通过调用这个函数发出请求:

fun facebookSignUp(access_token: String)
            :MutableLiveData<FacebookReturn>
        val items = MutableLiveData<FacebookReturn>()
        disposable = apiServe.facebookSignUp(
            access_token
        )
            .subscribeOn(Schedulers.io())
            .observeOn(androidSchedulers.mainThread())
            .subscribe(
                 result ->
                    items.postValue(result)
                    Log.d("Facebook API", result.toString())
                ,
                 error ->
                    Log.d("API ERROR", "API Fetch Error: $error.message ")
                
            )
        return items
    

API 运行良好,返回的数据如下所示:


    "facebook": 
        "statusCode": 200,
        "user": 
            "email": "Disguised",
            "firstName": "Disguised",
            "lastName": "Disguised",
            "token": "Disguised.eyJ1c2VybmFtZSI6bnVsbCwiZW1haWwiOiJwYXVsaXZhbl8zMDAwQHlhaG9vLmNvbSIsImlhdCI6MTYxNDg2NTk1OSwiZXhwIjoxNjE0ODY5NTU5fQ.q0Vn9_4d_-3_WcFfj9s7ZMD3I_0s6XWIEKvXCJuSa_w"
        
    

然后我尝试使用以下模型和 GSON 转换器库将此数据转换为 POJO 以进行改造:

data class FacebookReturn(
    val facebookUser: FacebookUser
)
data class FacebookUser(
    val statusCode: Int,
    val facebookUserDetails: FacebookUserDetails
)
data class FacebookUserDetails(
    val email: String,
    val firstName: String,
    val lastName: String,
    val token: String
)

但是,当我检查日志(标签:Facebook API)以查看对象时,即使 API 实际返回了数据,它也显示内容为空。下面我有 HttpInterceptor 创建的日志。我也看过类似的问题,但我认为这不是编码或映射问题,也许是,我不知道。

D/OkHttp: --> GET http://Disguised/auth/facebook?access_token=EAANAkZB2CDA4BAIhz74uPKfSZBO2qW52dcK8Qa3AzZASWCQ2Yu055yaUZATy71y92IGOiWpFwBsElRr8st4yhCRgbX2uIVauHMKA3TNyZBTsLcbkKbmMXFmnG9bP1ZBy3CNjJIqTRrqYbt76RhkIh9ZCg1A43kkfrzg6JBLZB9OoJRf5pEYbw8raJDl9nQD5sH5YpmzgD4J2Br4ZB4mHgMdHoFPXdRPdnxDORKcZCPUkkujQZDZD
    --> END GET
I/rventures.tree: Background concurrent copying GC freed 28459(2397KB) AllocSpace objects, 24(1248KB) LOS objects, 49% free, 5115KB/10230KB, paused 1.052ms total 540.715ms
D/OkHttp: <-- 200 OK http://Disguised/auth/facebook?access_token=EAANAkZB2CDA4BAIhz74uPKfSZBO2qW52dcK8Qa3AzZASWCQ2Yu055yaUZATy71y92IGOiWpFwBsElRr8st4yhCRgbX2uIVauHMKA3TNyZBTsLcbkKbmMXFmnG9bP1ZBy3CNjJIqTRrqYbt76RhkIh9ZCg1A43kkfrzg6JBLZB9OoJRf5pEYbw8raJDl9nQD5sH5YpmzgD4J2Br4ZB4mHgMdHoFPXdRPdnxDORKcZCPUkkujQZDZD (651ms)
    X-Powered-By: Express
    Access-Control-Allow-Origin: *
    Content-Type: application/json; charset=utf-8
    Content-Length: 317
    ETag: W/"13d-soe3iGc7MnKumoczrQKKLORbOpw"
    Date: Fri, 05 Mar 2021 05:15:05 GMT
    Connection: keep-alive
D/OkHttp: "facebook":"statusCode":200,"user":"email":"disguised@yahoo.com","firstName":"Disguised","lastName":"Disguised","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6bnVsbCwiZW1haWwiOiJwYXVsaXZhbl8zMDAwQHlhaG9vLmNvbSIsImlhdCI6MTYxNDkyMTMwNSwiZXhwIjoxNjE0OTI0OTA1fQ.6ml4yIu8e7KdrRyIcrAaDDZ8yZqi298utm49FKKccN4"
    <-- END HTTP (317-byte body)
D/Facebook API: FacebookUserDetails(email=null, firstName=null, lastName=null, token=null)
D/Facebook Return: FacebookUserDetails(email=null, firstName=null, lastName=null, token=null)

这可能是什么问题?

【问题讨论】:

您可以使用json2kotlin.com 映射json ot 数据类。顺便说一句,你在使用 gson 吗? 我正在使用 GSON 转换器 【参考方案1】:

您的类中的字段名称必须与 JSON 字段完全匹配,否则您将明确告诉 GSON 使用 @SerializedName("someName") 的名称。

您的某些字段与 JSON 不匹配,这可能是您没有将任何数据输入其中的原因。返回的 JSON 将 "facebook": 作为外部对象,因此在 FacebookReturn 中,您应该使用此序列化名称标记 val facebookUser(或将其重命名为“facebook”)。

data class FacebookReturn(
    @SerializedName("facebook")
    val facebookUser: FacebookUser
)

FacebookUser 中也是如此:

data class FacebookUser(
    val statusCode: Int,

    @SerializedName("user")
    val facebookUserDetails: FacebookUserDetails
)

【讨论】:

谢谢。我刚刚有一个朋友和我分享了这个,也正要发布我的答案,但你的回答很好。所以,是的,一个简单的错误几乎毁了我的一天。

以上是关于即使模型正确,来自 API 的响应也不会映射到对象的主要内容,如果未能解决你的问题,请参考以下文章

CORS - 即使在成功的 OPTIONS 响应之后,Firefox 也不会发送 API 调用

模型衍生 API 响应未通过 Jackson 映射

将 Json 响应中的对象列表映射到颤动中的列表

将 JSON 响应映射到 Vue.js 中的模型类

Java Spring Boot将rest api映射到模型[重复]

Django:将来自外部 API 的数据映射到模型中?