首先,抱歉我的英语不好。我有一个小问题,我的公司的应用程序,我开始学习Kotlin几个月前,所以它的一切对我来说都很新鲜,我做了一些小的挖掘我的大部分问题,但这一个我没有找到任何地方。我们有一个服务器provind数据与Joomla API,问题是,当我使用retrofit2来获得数据与查询,在没有找到数据时返回开始_OBJECT,而在找到数据时返回BEGIN_ARRAY。我发现很多地方告诉我们什么时候是一个,什么时候应该是另一个,但这两个都在同一个响应中,还没有。
这是找不到数据时的响应:
{"err_msg":"Produto n\u00e3o encontrado (CALOTA CORSA)","err_code":404,"response_id":"","api":"","version":"1.0","data":{}}
我将这部分的数据类命名为ProductList,而将数据命名为Product,以供将来参考...
这是找到数据时的响应:
{"err_msg":"","err_code":"","response_id":522,"api":"app.produto","version":"1.0","data":[{"codigo":"0340008","filial":"CPS","referencia":"7898314110118","ncm":"38249941","codigosecundario":"146","nome":"WHITE LUB SUPER AEROSSOL 300ML 146","similar":"0012861","parceiro":"","produtosrelacionados":"0012861;0125121;0125945;0340008;0340035;0340169;0343394;0582033;0582954;0610250;1203682;1227480;1227569;1366196;1366761;1450241;1450861","marca":"ORBI QUIMICA","linha":"DESENGRIPANTE","lancamento":"2011-07-28 00:00:00","quantidadeembalagem":"12","unidademedida":"PC","caracteristicas":"OLEO WHITE LUB SUPER AEROSSOL 300ML - DESENGRIPANTE\/ LUBRIFICANTE\/ PROTETIVO 146","lado":"N\/A","ultima_atualizacao_preco":"2022-08-05 10:32:53","valor":"9.99","ultima_atualizacao_estoque":"2022-09-01 00:03:17","estoque":"200"}]}
响应成功后,最多可收到10种不同的产品。
这是我在ViewModel上的改造调用,我正在使用带有改造功能的GsonConverterFactory。
fun getProductByCode(code: String, token: String) {
RetrofitInstance.chgApi.listProducts(code, token).enqueue(object : Callback<ProductList> {
override fun onResponse(call: Call<ProductList>, response: Response<ProductList>) {
if (response.body()?.errCode != "") {
Log.e("Response", response.body()?.errMsg!!)
errMsg.value = response.body()?.errMsg!!
} else {
errMsg.value = ""
products.value = response.body()!!.data
}
}
override fun onFailure(call: Call<ProductList>, t: Throwable) {
Log.e("Error", t.message.toString())
}
})
}
第一个数据类
data class ProductList(
@SerializedName("err_msg") var errMsg : String,
@SerializedName("err_code") var errCode : String,
@SerializedName("response_id") var responseId : String,
@SerializedName("api") var api : String,
@SerializedName("version") var version : String,
@SerializedName("data") var data: ArrayList<Product>
)
第二个数据类
@Entity(tableName = PRODUCT_DATABASE)
data class Product(
@PrimaryKey
@SerializedName("codigo" ) var codigo : String,
@SerializedName("filial" ) var filial : String,
@SerializedName("referencia" ) var referencia : String,
@SerializedName("ncm" ) var ncm : String,
@SerializedName("codigosecundario" ) var codigosecundario : String,
@SerializedName("nome" ) var nome : String,
@SerializedName("similar" ) var similar : String,
@SerializedName("parceiro" ) var parceiro : String,
@SerializedName("produtosrelacionados" ) var produtosrelacionados : String,
@SerializedName("marca" ) var marca : String,
@SerializedName("linha" ) var linha : String,
@SerializedName("lancamento" ) var lancamento : String,
@SerializedName("quantidadeembalagem" ) var quantidadeembalagem : String,
@SerializedName("unidademedida" ) var unidademedida : String,
@SerializedName("caracteristicas" ) var caracteristicas : String,
@SerializedName("lado" ) var lado : String,
@SerializedName("ultima_atualizacao_preco" ) var ultimaAtualizacaoPreco : String,
@SerializedName("valor" ) var valor : String,
@SerializedName("ultima_atualizacao_estoque" ) var ultimaAtualizacaoEstoque : String,
@SerializedName("estoque" ) var estoque : String,
var cesta : Int,
var comprar : Boolean
)
简单的处理方法是更改我的数据类,将字段“data”的类型更改为ArrayList< Product >或仅更改为Product,但是,据我所知,这两者不能同时使用......有什么建议吗?
2条答案
按热度按时间4ktjp1zp1#
假设,如您的答案所示,您有两个单独的模型类,一个用于成功响应,一个用于错误响应,以及一个公共超类型(例如接口X1M0N1X),您可以使用自定义的
JsonDeserializer
1来解决这个问题。它应该基于JsonObject
的成员和值来决定数据应该被反序列化为哪种类型。这样,您就可以保留data: List<Product>
作为ProductList
响应。(Note:您也可以使用在此处读取并用于模型类中的
@SerializedName
的单个常量,而不是在此处和模型类中复制字符串"err_code"
和"err_msg"
。)然后,您必须创建一个
GsonBuilder
,注册反序列化器,并使用Retrofit的GsonConverterFactory
来使用自定义的Gson
示例:在回调中,检查
Response
示例的类(它是ProductList
还是ProductListError
)。1:一般来说,
TypeAdapter
应该优先于JsonDeserializer
,因为它的性能更高,但由于这里的数据无论如何都需要被解析为JsonObject
,因此很可能没有区别。hjzp0vay2#
长话短说,我花了一整天的时间,我在这里找到了一个解决方案:
how to handle two different Retrofit response in Kotlin?
只是把我的Callback、Call和Response改为< Any >,创建一个新的模型,根据响应做一些处理。最后的代码: