我正在尝试为 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].myVal
映射到 myParsedData.myVar.myArray[x].myPersonalData.myVal
。即,myParsedData.myVar.myArray[x].myPersonalData.myVal
设置为null
。
请注意,我不想更改 JSON 结构或数据类结构,因为它是提供给我的。相反,我想要一种将 JSON 正确映射到数据类的方法。有没有更好的方法来做到这一点,而无需手动沿着树走下去并创建各个子节点的新实例?
您可以使用带有 Gson 的自定义反序列化器来处理嵌套属性的映射逻辑。为
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 中提取值并使用 MyArrayListValue
的正确映射构造 myPersonalData.myVal
对象。然后在创建 Gson 实例时使用 registerTypeAdapter
向 Gson 注册自定义反序列化器。
希望有帮助!