Десериализация Гсона для списка в Котлине - PullRequest
0 голосов
/ 01 июня 2019

Вот как выглядит мой 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 ]

0 голосов
/ 01 июня 2019

Массив 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>
)
0 голосов
/ 01 июня 2019

Попробуйте заменить

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

с

val listType: Type = object : TypeToken<MutableList<Role>>() {}.type
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...