【问题标题】:Convert JSON to POJO with different data type将 JSON 转换为具有不同数据类型的 POJO
【发布时间】:2021-05-02 00:03:39
【问题描述】:

我有这个回复,当我想转换为 pojo 时遇到问题。

"equity": {
            "0": {
                "name": [
                    "Abc"
                ],
                "code": [
                    "3410"
                ],
                "ending_balance": [
                    301834470
                ]
            },
            "1": {
                "name": [
                    "Xyz"
                ],
                "code": [
                    "2180"
                ],
                "ending_balance": [
                    0
                ]
            },
            "2": {
                "name": [
                    "Pqr"
                ],
                "code": [
                    "9220"
                ],
                "ending_balance": [
                    0
                ]
            },
            "total_equity": 301834470
        }
    }

我对提供正确的数据类型感到困惑,因为有包含对象的数组(“0”、“1”、“2”)和包含数字的“total_equity”。 我尝试提供地图数据类型,但“total_equity”会出错

var equity: Map<String, EquityDto?>

如果您知道此问题的解决方案,请帮助我。谢谢

【问题讨论】:

  • 您的 Json 错误。一级(权益)作为对象开放,但它应该是一个数组。你也是2级。
  • 为什么不使用array 而不是对象来重复keys
  • 我没有做api,我只是消费它

标签: android json kotlin retrofit pojo


【解决方案1】:

你可以使用

var equity: Map<String, Any>

在访问任何数据类型时,您可以比较可变类型(实例)并使用以下值

if (valueofMap is Int){
//here is integer value
}

if (valueofMap is yourDataClass){
//your custom class
}

【讨论】:

  • 当我想将 Any 转换为我的数据类时会导致错误
  • 我使用 'as' 将 Any 投射到我的班级
  • 欢迎。请给我一个接受和支持
  • 当我将 valueOfMap 与 myDataClass 进行比较时,它总是返回 false。
  • 当我记录 valueOfMap 它返回 {classification=Abcd, name=[xyz], code=[1234], ending_balance=[1000.0], total=1000.0} 并且我的数据类是数据类 Item (var分类:String?= null,var名称:List?= null,var代码:List?= null,var ending_balance:List?= null,var total:Double?= 0.0)我的数据类错了吗?
【解决方案2】:

有办法解决这个问题,但会很长。

一种解决方案是将响应转换为Map&lt;String, Any&gt;,然后您必须在每次必须使用它时检查类型,并且在多个类中使用它时真的很烦人。

另一种解决方案是创建一个自定义Custom Type Adapter,您可以将其传递给addConverterFactory 方法中的Retrofit 实例。

要创建自定义适配器,您只需按照以下步骤操作:

  1. 创建要在其中存储数据的模型。在你的情况下,它可以是:

data class ApiResponse(
     val data: Map<String, EquityDto?>,
     val totalEquity:Int
)

  1. 创建适配器:

class StudentAdapter : TypeAdapter<ApiResponse?>() {
    @Throws(IOException::class)
    fun read(reader: JsonReader): ApiResponse {
        val student:ApiResponse? = null
        reader.beginObject()
        var fieldname: String? = null
        while (reader.hasNext()) {
            var token = reader.peek()
            if (token == JsonToken.NAME) {
                //get the current token
                fieldname = reader.nextName()
            }

            if ("total_equity" == fieldname) {
                token = reader.peek()
                student?.totalEquity = reader.nextInt()
            }else {
                token = reader.peek()
                student?.data?.set(fieldname.toString(), reader.nextString())
            }
        }
        reader.endObject()
        return student
    }

    @Throws(IOException::class)
    fun write(writer: JsonWriter, student: ApiResponse) {
        writer.beginObject()
        writer.name("data")
        writer.value(student.data.toString())
        writer.name("totalEquity")
        writer.value(student.totalEquity)
        writer.endObject()
    }
}

如果您知道创建类型适配器的更好方法,那么您肯定可以使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2019-07-24
    • 1970-01-01
    • 2022-07-24
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多