我有api返回json:
{"countries":[{"id":1,"name":"Australia"},{"id":2,"name":"Austria"}, ... ]}
我写模特课(Kotlin lang)
data class Country(val id: Int, val name: String)
我想要使用retorift返回List< Models.Country>,来自json的“countries”字段
我接下来写道:
interface DictService {
@GET("/json/countries")
public fun countries(): Observable<List<Models.Country>>
companion object {
fun create() : DictService {
val gsonBuilder = GsonBuilder()
val listType = object : TypeToken<List<Models.Country>>(){}.type
gsonBuilder.registerTypeAdapter(listType, CountriesDeserializer)
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
val service = Retrofit.Builder()
.baseUrl("...")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
.build()
return service.create(DictService::class.java)
}
}
object CountriesDeserializer : JsonDeserializer<List<Models.Country>> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): List<Models.Country>? {
val res = ArrayList<Models.Country>()
if(json!=null) {
val countries = json.asJsonObject.get("countries")
if (countries.isJsonArray()) {
for (elem: JsonElement in countries.asJsonArray) {
res.add(Gson().fromJson(elem, Models.Country::class.java))
}
}
}
return null;
}
}
}
但我收到错误: java.lang.IllegalStateException:预期为BEGIN_ARRAY,但在第1行第2行路径为$ BEGIN_OBJECT CountriesDeserializer代码甚至不执行! 他们想要我什么?
也许我需要编写自己的TypeAdapterFactory?
我不想使用像
这样的模型类class Countries {
public List<Country> countries;
}
答案 0 :(得分:2)
如果您的目的是简化界面并隐藏中间包装器对象,我想最简单的方法是将扩展方法添加到DictService
,如下所示:
interface DictService {
@GET("/json/countries")
fun _countries(): Observable<Countries>
}
fun DictService.countries() = _countries().map { it.countries }
data class Countries(val countries: List<Country> = listOf())
然后可以按如下方式使用:
val countries:Observable<List<Country>> = dictService.countries()
答案 1 :(得分:0)
我找到了方法:
varList :: LExpTree Lukasiewicz -> [String]
但我认为这是一个非常复杂的决定。 还有另外一种更简单的方法吗?
另一个: 我从初始代码中发现了错误! 如果用ArrayList替换List,它可以正常工作!
答案 2 :(得分:0)
我会用杰克逊完成这项任务。 试试这个https://github.com/FasterXML/jackson-module-kotlin
val mapper = jacksonObjectMapper()
data class Country(val id: Int, val name: String)
// USAGE:
val country = mapper.readValue<Country>(jsonString)