如何让我的 retrofit2 模型解析这个?
Posted
技术标签:
【中文标题】如何让我的 retrofit2 模型解析这个?【英文标题】:How to get my retrofit2 model to parse this? 【发布时间】:2021-11-08 11:16:27 【问题描述】:这是异常的响应,其中对象的名称与对象的 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()
)
地址部分之外的所有内容都很好,因为我使用带有 null 的地址的响应对其进行了测试,我尝试为此进行反序列化,但它似乎无法识别它,这就是它的样子
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())
响应的结构是这样的
Call<List<Event>>
但列表总是有 1 个元素,这是我无法更改的旧 api 的工件
【问题讨论】:
一个地址显然不是一个事件。您甚至在问什么都非常不清楚。此外,当使用转换器时,所有手动反序列化确实是完全无意义的。 地址是事件对象的一部分。我能够解决地址部分之外的所有问题,并且只有这部分响应是异常且难以解析的,这就是我需要帮助的地方。反序列化器方法失败了,但我将它包括在内只是为了展示我尝试过的内容。 【参考方案1】:好的,所以我想通了,显然您的反序列化器需要与您的响应的类型完全相同,因此我添加了拦截器,该拦截器删除了包装每个响应的多余数组,现在反序列化器正在按预期使用。
【讨论】:
以上是关于如何让我的 retrofit2 模型解析这个?的主要内容,如果未能解决你的问题,请参考以下文章