如何在改造中制作通用序列化名称?

How to make a generic serialized name in retrofit?

我的大多数 API 呼叫 return 是这样的:

{
  "message": str,
  "status": str,
  "different_name_depending_on_endpoint":{
    // bunch of stuff
  },
}

如何使 "different_name_depending_on_endpoint" 键中的名称通用?像这样:

data class ReturnAPI<T>(
    @SerializedName("message")
    val message: String,
    @SerializedName("status")
    val status: String,
    @SerializedName("how do I make this generic")
    val data: T
)

否则,对于每个端点,我必须为 api return 创建一个单独的数据 class,并为 data 创建一个单独的数据 class领域,这是不切实际的。一定有办法让它通用,对吧?或者告诉 Retrofit 尝试用 JSON 文件中不是 messagestatus.[=19 的任何其他内容填充 data 字段=]

Or to tell Retrofit to try to fill the data field with whatever else is in the JSON file that isn't message or status

是的,您可以为 ReturnAPI 类型编写自定义反序列化程序:

@JsonAdapter(ReturnApiTypeAdapter::class)
data class ReturnAPI<T>(
    val message: String,
    val status: String,
    val data: T
)

class ReturnApiTypeAdapter : JsonDeserializer<ReturnAPI<*>> {

    @Throws(JsonParseException::class)
    override fun deserialize(
        json: JsonElement,
        typeOfT: Type,
        context: JsonDeserializationContext
    ): ReturnAPI<*>? {
        if (json.isJsonNull) {
            return null
        }
        val jsonObject = json.asJsonObject
        // get actual type of Data
        val typeOfData = (typeOfT as ParameterizedType)
            .actualTypeArguments[0]

        var message: String? = null
        var status: String? = null
        var data: Any? = null

        for (key in jsonObject.keySet()) {
            when (key) {
                "message" -> message = jsonObject.getAsJsonPrimitive(key).asString
                "status" -> status = jsonObject.getAsJsonPrimitive(key).asString
                else -> data = context.deserialize(jsonObject.get(key), typeOfData)
            }
        }
        // optional checks
        check(message != null && status != null) {
            "Failed parsing"
        }
        return ReturnAPI(message, status, data)
    }
}