使用自定义 Gson 反序列化器反序列化 JSON 响应时出错
Error deserializing JSON response with custom Gson deserializer
在我使用 Retrofit 的 Android 应用程序中,我正在尝试反序列化 JSON,它有一个包含项目列表的外部对象。我将 GsonConverterFactory 与 Retrofit 实例一起使用来反序列化 JSON。我创建了一个自定义反序列化器以仅从响应中提取项目列表,因此我不必创建父包装器 class。我以前用 Java 做过这个,但我无法让它与 Kotlin 一起工作。当调用 ItemsService 获取 Items 时,出现以下异常:java.lang.IllegalStateException:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处 BEGIN_OBJECT
我的反序列化器是否有问题,或者我如何使用 Gson 和 Retrofit 配置它?我还有什么地方做错了吗?
JSON:
{
"items" : [
{
"id" : "item1"
},
{
"id" : "item2"
},
{
"id" : "item3"
}
}
解串器:
class ItemsDeserializer : JsonDeserializer<List<Item>> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): List<Item> {
val items: JsonElement = json!!.asJsonObject.get("items")
val listType= object : TypeToken<List<Item>>() {}.type
return Gson().fromJson(items, listType)
}
}
项目:
data class Item (val id: String)
物品服务:
interface ItemsService {
@GET("items")
suspend fun getItems(): List<Item>
}
服务工厂:
object ServiceFactory {
private const val BASE_URL = "https://some.api.com"
private val gson = GsonBuilder()
.registerTypeAdapter(object : TypeToken<List<Item>>() {}.type, ItemsDeserializer())
.create()
fun retrofit(): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
val itemsService: ItemsService = retrofit().create(ItemsService::class.java)
}
哦,这是一个很常见的错误。您必须使用 TypeToken.getParameterized
创建参数化类型。所以你必须将 object : TypeToken<List<Item>>() {}.type
更改为 TypeToken.getParameterized(List::class.java, Item::class.java).type
class ItemsDeserializer : JsonDeserializer<List<Item>> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): List<Item> {
val items: JsonElement = json!!.asJsonObject.get("items")
val listType= TypeToken.getParameterized(List::class.java, Item::class.java).type
return Gson().fromJson(items, listType)
}
}
private val gson = GsonBuilder()
.registerTypeAdapter(TypeToken.getParameterized(List::class.java, Item::class.java).type, ItemsDeserializer())
.create()
在我使用 Retrofit 的 Android 应用程序中,我正在尝试反序列化 JSON,它有一个包含项目列表的外部对象。我将 GsonConverterFactory 与 Retrofit 实例一起使用来反序列化 JSON。我创建了一个自定义反序列化器以仅从响应中提取项目列表,因此我不必创建父包装器 class。我以前用 Java 做过这个,但我无法让它与 Kotlin 一起工作。当调用 ItemsService 获取 Items 时,出现以下异常:java.lang.IllegalStateException:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处 BEGIN_OBJECT
我的反序列化器是否有问题,或者我如何使用 Gson 和 Retrofit 配置它?我还有什么地方做错了吗?
JSON:
{
"items" : [
{
"id" : "item1"
},
{
"id" : "item2"
},
{
"id" : "item3"
}
}
解串器:
class ItemsDeserializer : JsonDeserializer<List<Item>> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): List<Item> {
val items: JsonElement = json!!.asJsonObject.get("items")
val listType= object : TypeToken<List<Item>>() {}.type
return Gson().fromJson(items, listType)
}
}
项目:
data class Item (val id: String)
物品服务:
interface ItemsService {
@GET("items")
suspend fun getItems(): List<Item>
}
服务工厂:
object ServiceFactory {
private const val BASE_URL = "https://some.api.com"
private val gson = GsonBuilder()
.registerTypeAdapter(object : TypeToken<List<Item>>() {}.type, ItemsDeserializer())
.create()
fun retrofit(): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
val itemsService: ItemsService = retrofit().create(ItemsService::class.java)
}
哦,这是一个很常见的错误。您必须使用 TypeToken.getParameterized
创建参数化类型。所以你必须将 object : TypeToken<List<Item>>() {}.type
更改为 TypeToken.getParameterized(List::class.java, Item::class.java).type
class ItemsDeserializer : JsonDeserializer<List<Item>> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): List<Item> {
val items: JsonElement = json!!.asJsonObject.get("items")
val listType= TypeToken.getParameterized(List::class.java, Item::class.java).type
return Gson().fromJson(items, listType)
}
}
private val gson = GsonBuilder()
.registerTypeAdapter(TypeToken.getParameterized(List::class.java, Item::class.java).type, ItemsDeserializer())
.create()