代码之家  ›  专栏  ›  技术社区  ›  Muhammad Ahmed AbuTalib

Kotlin中列表的Gson反序列化

  •  -1
  • Muhammad Ahmed AbuTalib  · 技术社区  · 6 年前

    这就是我的json

    {
      "sub": "9",
    
      "auth_time": 1559381757,
      "idp": "idsrv",
    
      "role": [
        "Employer",
        "Employee",
        "Student"
      ],
    
    
      "iss": "",
      "aud": "",
      "exp": 1574933757,
      "nbf": 1559381757
    }
    

    这是我要将此Json转换为的对象。

    data class Claims (
        @SerializedName("nameid") val nameId: String,
        @SerializedName("unique_id") val uniqueId: String,
        @SerializedName("sub") val sub: String,
        @SerializedName("unifiedNumber") val unifiedNumber: String,
        @SerializedName("role") var roleList: List<Role>
    )
    

    我为列表类型编写了一个自定义反序列化程序(在Java中工作)

    class RoleDeserializer : JsonDeserializer<List<Role>> {
    
        private var roleId = 0
        @Throws(JsonParseException::class)
        override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): MutableList<Role> {
            val resultList = ArrayList<Role>()
            if (json.isJsonArray) {
                for (e in json.asJsonArray) {
                    resultList.add(Role(id = roleId++, name = e.asString))
                }
            } else if (json.isJsonObject) {
                resultList.add(Role(id = roleId++, name = json.asString))
            } else if (json.isJsonPrimitive) {
                if ((json as JsonPrimitive).isString)
                    resultList.add(Role(id = roleId++, name = json.getAsString()))
            } else {
                throw RuntimeException("Unexpected JSON type: " + json.javaClass)
            }
            return resultList
        }
    }
    

    这就是我注册类型适配器的方式

    val listType: Type = object : TypeToken<List<Role>>() {}.type
            val gson = GsonBuilder().registerTypeAdapter(listType, RoleDeserializer()).create()
            val claims = gson.fromJson(stringJson, Claims::class.java)
    

    我仍然收到一个解析异常,声明

    java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 161 path $.role[0]
    

    我的RoleDeserializer永远不会被调用。注册类型适配器时我做错了什么吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   Saeed Masoumi    6 年前

    尝试替换

    val listType: Type = object : TypeToken<List<Role>>() {}.type
    

    具有

    val listType: Type = object : TypeToken<MutableList<Role>>() {}.type
    
        2
  •  0
  •   AskNilesh    6 年前

    这个 role 字符串数组是否在 JSON

    用这个

    @SerializedName("role") var roleList: List<String>
    

    而不是这个

    @SerializedName("role") var roleList: List<Role>
    

    试试这个

    data class Claims (
        @SerializedName("nameid") val nameId: String,
        @SerializedName("unique_id") val uniqueId: String,
        @SerializedName("sub") val sub: String,
        @SerializedName("unifiedNumber") val unifiedNumber: String,
        @SerializedName("role") var roleList: List<String>
    )