【问题标题】:TypeAdapter to serialize/deserialize an object inside a Model ClassTypeAdapter 序列化/反序列化模型类中的对象
【发布时间】:2020-01-26 15:25:41
【问题描述】:

我有一个如下所示的 JSON 响应:

[{
    "id":"61051",
    "employee_name":"koiudshau",
    "employee_salary":"111",
    "employee_age":"0",
    "profile_image":""
},
{
    "id":"61071",
    "employee_name":"Nickky Raboy",
    "employee_salary":"1234",
    "employee_age":"20",
    "profile_image":""
}]

我想创建一个自定义类型适配器,它将 value employee_name 拆分为 firstName 和 secondName 并将它们存储为名为 @987654325 的 object @,其中包含firstName 和secondName 作为参数。这必须在反序列化期间完成。

在序列化期间,Name 类型的对象必须转换为String(反序列化前的类型相同)。

这些是我尝试过的代码。

模型类:

data class Employee (
    @SerializedName("id")
    val id: Int = 0,
    @SerializedName("employee_name")
    val employee_name: Name,
    @SerializedName("employee_salary")
    val employee_salary: Float = 0f,
    @SerializedName("employee_age")
    val employee_age: Int = 0,
    @SerializedName("profile_image")
    val profile_image : String = ""
)

data class Name(val firstName : String = "" , val secondName : String = "")

CustomizedTypeAdapterFactory:

abstract class CustomizedTypeAdapterFactory<C>(private val customizedClass: Class<C>) : TypeAdapterFactory {
    override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
        return if (type.rawType == customizedClass) customizeMyClassAdapter(gson, type as TypeToken<C>) as TypeAdapter<T> else null
    }
    private fun customizeMyClassAdapter(gson: Gson, type: TypeToken<C>): TypeAdapter<C> {
        val delegate = gson.getDelegateAdapter(this, type)
        val elementAdapter = gson.getAdapter(JsonElement::class.java)
        return object : TypeAdapter<C>() {
            @Throws(IOException::class)
            override fun write(out: JsonWriter, value: C) {
                val tree = delegate.toJsonTree(value)
                beforeWrite(value, tree)
                elementAdapter.write(out, tree)
            }
            @Throws(IOException::class)
            override fun read(`in`: JsonReader): C {
                val tree = elementAdapter.read(`in`)
                afterRead(tree)
                return delegate.fromJsonTree(tree)
            }
        }
    }
    protected open fun beforeWrite(source: C, toSerialize: JsonElement) {}
    protected open fun afterRead(deserialized: JsonElement) {}
}

MyClassTypeAdapterFactory:

class MyClassTypeAdapterFactory : CustomizedTypeAdapterFactory<Name>(Name::class.java) {
    override fun beforeWrite(source: Name, toSerialize: JsonElement) {
        val custom = toSerialize.asJsonObject.get("employee_name").asJsonObject
        custom.add("size", JsonPrimitive(custom.entrySet().size))
    }
    override fun afterRead(deserialized: JsonElement) {
        val custom = deserialized.asJsonObject.get("employee_name").asJsonObject
        custom.remove("size")
    }
}

RetrofitBuilder :

private var retrofitBuilder: Retrofit.Builder = Retrofit.Builder().baseUrl(API_BASE_URL).addConverterFactory(createGsonConverter()).client(okHttpClientBuilder.build())

createGsonConverter():

private fun createGsonConverter() : Converter.Factory {
    val gsonBuilder = GsonBuilder()
    gsonBuilder.registerTypeAdapterFactory(MyClassTypeAdapterFactory())
    val gson = gsonBuilder.create()
    return GsonConverterFactory.create(gson)
}

当我运行此代码时,应用程序崩溃并显示此日志消息:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.shaheen.gsonparsing, PID: 15147
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Not a JSON Object: "Karolina38606"

【问题讨论】:

  • 你能分享你的模型类吗?

标签: android serialization gson deserialization retrofit2


【解决方案1】:

“employee_name”是字符串而不是 jsonobject

【讨论】:

    【解决方案2】:

    通过更改 CustomizedTypeAdapterFactory 类和 createGsonConverter() 方法,我得到了所需的输出,如下所示:

    CustomizedTypeAdapterFactory:

    class CustomizedTypeAdapterFactory : TypeAdapter<Name>() {
        override fun write(out: JsonWriter?, value: Name?) {
            out!!.value("${value?.firstName} ${value?.secondName}")
        }
    
        override fun read(`in`: JsonReader?): Name {
            var lastName = ""
            var firstName = ""
            val employeeName = `in`!!.nextString()
            if (employeeName!=null) {
                val name = employeeName.split(" ")
                if(name.size > 1){
                    lastName += name[name.size - 1]
                    for (element in 0 until (name.size - 1)){
                        firstName = if (element == (name.size - 1)) "$firstName${name[element]}" else "$firstName${name[element]} "
                    }
                }
                else firstName = name[0]
            }
            return Name(firstName,lastName)
        }
    }
    
    

    createGsonConverter():

    private fun createGsonConverter() : Converter.Factory {
        val gsonBuilder = GsonBuilder()
        gsonBuilder.registerTypeAdapter(Name::class.java,CustomizedTypeAdapterFactory()).setLenient()
        val gson = gsonBuilder.create()
        return GsonConverterFactory.create(gson)
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      相关资源
      最近更新 更多