gson 如何让我的retrofit2模型解析这个?

yqyhoc1h  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(169)

这是一个异常响应,其中对象的名称与对象的ID相同,此时我真的不知道如何解析此响应

"addresses": {
            "163492": {
                "address_id": "163492",
                //more of String variables
            },
            "166127": {
                "address_id": "166127",
                //more of String variables
            },
            "166202": {
                "address_id": "166202",
                //more of String variables
            }
        }

这是我的事件模型的外观,我稍后将使用房间数据库保存此响应

@Entity
data class Event(
    @PrimaryKey(autoGenerate = false)
    @SerializedName("id") val id: Int,
    @SerializedName("title") val title: String,
    @SerializedName("description") val desc: String,
    @SerializedName("note") val note: String? = null,
    @SerializedName("date") val dateTs: Long,
    @SerializedName("begintime") val beginTime: String,
    @SerializedName("enddate") val endDate: String,
    @SerializedName("endtime") val endTime: String,
    @SerializedName("customerid") val customerId: String? = null,
    @SerializedName("address_id") val addressId: String? = null,
    @SerializedName("pin") val pin: String? = null,
    @SerializedName("location") val location: String? = null,
    @SerializedName("customerlocation") val customerLocation: String? = null,
    @field:TypeConverters(beskidmedia.pl.scanner.room.TypeConverters::class)
    @SerializedName("nodes") val nodes: List<Node>? = null,
    @SerializedName("closed") val closed: Int,
    @SerializedName("type") val type: Int,
    @SerializedName("ticketid") val ticketId: String? = null,
    @SerializedName("customername") val customerName: String? = null,
    @field:TypeConverters(beskidmedia.pl.scanner.room.TypeConverters::class)
    @SerializedName("contacts") val contacts: List<Contacts>? = null,
    @field:TypeConverters(beskidmedia.pl.scanner.room.TypeConverters::class)
    @SerializedName("addresses") val addresses: List<Address>? = null,
    @Embedded
    @SerializedName("assignments") val assignments: Assignments? = null,
    @SerializedName("lastUpdate") val lastUpdate: Long = System.currentTimeMillis()
)

除了地址部分之外的一切都很好,因为我使用响应对地址进行了测试,我试图对此进行反序列化,但它似乎无法识别它,这是它的外观

class EventDeserializer : JsonDeserializer<Event> {
    override fun deserialize(
        json: JsonElement?,
        typeOfT: Type?,
        context: JsonDeserializationContext?
    ): Event {
        json?.asJsonObject!!.let { event ->
            val nodes = mutableListOf<Node>()
            val contacts = mutableListOf<Contacts>()
            val addresses = mutableListOf<Address>()

            val net = mutableListOf<Assignment>()
            val tv = mutableListOf<Assignment>()
            val assignments = Assignments(net, tv)

            val netTemp = event.get("assignments").asJsonObject.get("assignments_net").asJsonArray
            val tvTemp = event.get("assignments").asJsonObject.get("assignments_tv").asJsonArray

            netTemp.forEach { assignment ->
                assignment.asJsonObject.let {
                    net.add(
                        Assignment(
                            name = it.get("name").asString,
                            id = it.get("id").asInt
                        )
                    )
                }
            }

            tvTemp.forEach { assignment ->
                assignment.asJsonObject.let {
                    tv.add(
                        Assignment(
                            name = it.get("name").asString,
                            id = it.get("id").asInt
                        )
                    )
                }
            }

            val nodesTemp = event.get("nodes").asJsonArray
            nodesTemp.forEach { node ->
                node.asJsonObject.let {
                    nodes.add(
                        Node(
                            id = it.get("id").asInt,
                            name = it.get("name").asString,
                            mac = it.get("mac").asString,
                            ip = it.get("ip").asString,
                            location = it.get("location").asString,
                            netName = it.get("netname").asString
                        )
                    )
                }
            }

            val contactsTemp = event.get("contacts").asJsonArray
            contactsTemp.forEach { contact ->
                contact.asJsonObject.let {
                    contacts.add(
                        Contacts(
                            phone = it.get("phone").asString,
                            contact = it.get("contact").asString,
                            name = it.get("name").asString,
                            type = it.get("type").asString,
                            typeStr = it.get("typestr").asString
                        )
                    )
                }
            }

            val addressesTemp = event.get("addresses").asJsonObject
            addressesTemp?.keySet()?.let { names ->
                names.forEach { name ->
                    addressesTemp.get(name).asJsonObject.let {
                        addresses.add(
                            Address(
                                id = it.get("address_id").asString,
                                name = it.get("location").asString
                            )
                        )
                    }
                }
            }

            return Event(
                id = event.get("id").asInt,
                title = event.get("title").asString,
                desc = event.get("description").asString,
                note = event.get("note")?.asString,
                dateTs = event.get("date").asLong,
                beginTime = event.get("begintime").asString,
                endDate = event.get("enddate").asString,
                endTime = event.get("endtime").asString,
                customerId = event.get("customerid")?.asString,
                addressId = event.get("address_id")?.asString,
                pin = event.get("pin")?.asString,
                location = event.get("location")?.asString,
                customerLocation = event.get("customerlocation")?.asString,
                nodes = nodes,
                closed = event.get("closed").asInt,
                type = event.get("type").asInt,
                ticketId = event.get("ticketid")?.asString,
                customerName = event.get("customername")?.asString,
                contacts = contacts,
                addresses = addresses,
                assignments = assignments
            )
        }

    }
}

这就是我如何创建Gson工厂

val gson = GsonBuilder().registerTypeAdapter(Event::class.java, EventDeserializer())
Retrofit
                .Builder()
                .baseUrl(API_BASE_URL)
                .addConverterFactory(
                    GsonConverterFactory.create(gson.create())
                )
                .callbackExecutor(Executors.newSingleThreadExecutor())

React的结构是这样的

Call<List<Event>>

但列表始终有1个元素,这是旧API的产物,我无法更改

ukxgm1gy

ukxgm1gy1#

好了,我明白了,显然你的反序列化器需要和你的响应是完全相同的类型,所以我添加了拦截器,删除了 Package 每个响应的多余数组,现在反序列化器按预期使用了。

相关问题