方法有很多,你可以自己拿responseBody
里的json
酱虎,一個(gè)個(gè)字段自己解析雨膨;也可以給okhttp
添加攔截器來處理response內(nèi)容。
這里提供一種簡便的方法读串。
Gson
在反序列化的時(shí)候聊记,默認(rèn)是將{}
轉(zhuǎn)成LinkedTreeMap
,[]
轉(zhuǎn)成ArrayList
恢暖,value是數(shù)字的全部定義為了double排监。
如果后端返回格式不規(guī)矩或者會(huì)變化的時(shí)候,將bean里定義的是Any
或*
即可
比如有時(shí)返回的是這樣
image.png
有時(shí)是這樣
image.png
可以看到
event
雖然都是個(gè)數(shù)組杰捂,可里面的內(nèi)容完全就不一樣舆床,于是我就定義倆個(gè)data class
,分別為ZulipMessage
和DelMsgEventDTO
data class ZulipEventDTO(
val events: List<LinkedTreeMap<String,Any>>
)
event
定義是一個(gè)集合嫁佳,泛型就是Gson
默認(rèn)的LinkedTreeMap<String,Any>
,這樣不管是那種數(shù)據(jù)都可以接受到挨队。并且存入map中。
解析的時(shí)候脱拼,根據(jù)event.type
的類型瞒瘸,解析成不同的類。
private val parseMapGson = GsonBuilder().enableComplexMapKeySerialization().create() //重點(diǎn)行
eventDTO.events.forEach { event ->
when (event["type"]) {
//根據(jù)type類型熄浓,解析成不同的類
ZulipConst.EVENT_TYPE_MESSAGE -> {
val messageJson = parseMapGson.toJson(event[ZulipConst.EVENT_TYPE_MESSAGE]) // 先將LinkedList轉(zhuǎn)成json
val zulipMessage = parseMapGson.fromJson<ZulipMessage>(messageJson, ZulipMessage::class.java) //再根據(jù)類型轉(zhuǎn)成bean對象
saveMsg2Database(zulipMessage)
}
ZulipConst.EVENT_TYPE_DELETE_MESSAGE -> {
val messageJson = parseMapGson.toJson(event[ZulipConst.EVENT_TYPE_DELETE_MESSAGE])
val delMsgEventDTO = parseMapGson.fromJson<ZulipMessage>(messageJson, DelMsgEventDTO::class.java)
delMsgFromDb(delMsgEventDTO)
}
else -> {
}
}
// Any被轉(zhuǎn)成LinkedTreeMap時(shí)情臭,所有數(shù)字都是double
val eventId = (event["id"] as Double).toLong()
if (eventId > lastEventId) {
lastEventId = eventId
}
}
總結(jié):有type
能幫忙判斷返回?cái)?shù)據(jù)類型的省撑,那就根據(jù)類型定義不同的類,先用LinkedTreeMap
接住數(shù)據(jù)俯在,再根據(jù)類型轉(zhuǎn)就是了竟秫。
如果沒有type
這種字段,完全無法預(yù)料返回的是個(gè)什么跷乐,那不妨就從LinkedTreeMap中直接取數(shù)據(jù)肥败。