gson 如何将一个jsonMap到一个有嵌套 Package 器子级的数据类?

ubby3x7f  于 2024-01-08  发布在  其他
关注(0)|答案(1)|浏览(213)

我正在尝试为GraphQL解析器编写一个单元测试。我有这样的JSON文件结构:

{
     "data": {
         "myVar": {
              "myArray": [{
                         "someVal": "someStr1",
                         "myVal": "myStr1", 
                   }, {
                         "someVal": "someStr2",
                         "myVal": "myStr2"
                   }
               ]
         }
     }
}

字符串
这是我的MyDataClass.kt:

data class MyDataClass(
     myVar: MyBaseVar? = null
)

data class MyBaseVar(
    myArray: List<MyArrayListValue>? = null
)

data class MyArrayListValue(
     someVal: String? = null
     myPersonalData: MyPersonalData? = null
)

data class MyPersonalData( // The wrapper class around `myVal`
     myVal: String? = null
)


我正在使用

val jsonData = JsonParser.parseString(
     javaClass.getResourceAsStream(myJsonFile)!!.reader().readText()
).asJsonObject.get("data")

val myParsedData = Gson().fromJson(jsonData, MyDataClass::class.java)


然而,由于JSON结构和数据类之间存在细微的差异,我无法将data.myVar.myArray[x].myValMap到myParsedData.myVar.myArray[x].myPersonalData.myVal。也就是说,myParsedData.myVar.myArray[x].myPersonalData.myVal被设置为null
请注意,我不想更改JSON结构或Data类结构,因为这是提供给我的东西。相反,我希望有一种方法可以正确地将JSONMap到数据类。有没有更好的方法可以做到这一点,而不必手动遍历树并创建单个子节点的新示例?

qc6wkl3g

qc6wkl3g1#

您可以使用Gson的自定义解析器来处理嵌套属性的Map逻辑。为MyArrayListValue编写自定义解析器,从JSON结构中提取myVal字段并将其设置为myPersonalData.myVal,您可以按照以下代码操作:

import com.google.gson.*
import java.lang.reflect.Type

data class MyDataClass(
    val myVar: MyBaseVar? = null
)

data class MyBaseVar(
    val myArray: List<MyArrayListValue>? = null
)

data class MyArrayListValue(
    val someVal: String? = null,
    val myPersonalData: MyPersonalData? = null
)

data class MyPersonalData(
    val myVal: String? = null
)

class MyArrayListValueDeserializer : JsonDeserializer<MyArrayListValue> {
    override fun deserialize(
        json: JsonElement,
        typeOfT: Type?,
        context: JsonDeserializationContext?
    ): MyArrayListValue {
        val jsonObject = json.asJsonObject
        val someVal = jsonObject.get("someVal")?.asString
        val myVal = jsonObject.get("myVal")?.asString

        val myPersonalData = MyPersonalData(myVal)

        return MyArrayListValue(someVal, myPersonalData)
    }
}

fun main() {
    val gson = GsonBuilder()
        .registerTypeAdapter(MyArrayListValue::class.java, MyArrayListValueDeserializer())
        .create()

    val myJsonFile = "path/to/your/json/file.json"
    val jsonData = JsonParser.parseString(
        javaClass.getResourceAsStream(myJsonFile)!!.reader().readText()
    ).asJsonObject.get("data")

    val myParsedData = gson.fromJson(jsonData, MyDataClass::class.java)

    // Now myParsedData should have the correct mapping for myPersonalData.myVal
    println(myParsedData)
}

字符串
在上面的代码中,MyArrayListValueDeserializer类扩展了JsonDeserializer<MyArrayListValue>并覆盖了deserialize方法。在这个方法中,它手动从JSON中提取值,并使用myPersonalData.myVal的正确Map构造MyArrayListValue对象。然后,在创建Gson示例时,使用registerTypeAdapter将自定义解析器注册到Gson。

  • 希望有帮助!*

相关问题