当使用改造从远程获取json并将其解析为pojo时, 并且json在每个项目中都有“类型”,根据类型将创建不同的pojo类。
{
"result": [
{
"type": "stroy",
"stroy_data_1": xxx,
"story_data_2": yyy
},
{
"type": "detail",
"detail_data_1": 111,
"detail_data_2": 222
}
]
}
通过改型,可以由addConverterFactory
和Converter.Factory
完成,例如:
这里用RuntimeTypeAdapterFactory
构建dataAdapter
来创建Gson并要求根据“类型”创建calsons
fun createCustomeDataGson(): Gson {
val dataAdapter = RuntimeTypeAdapterFactory
.of(TopLevelItem::class.java, "type")
.registerSubtype(Story::class.java, "story")
.registerSubtype(Detail::class.java, "detail")
return GsonBuilder()
.registerTypeAdapterFactory(dataAdapter)
.create()
}
使用Gson创建Converter.Factory,以改装为addConverterFactory
fun getGsonConverterFactory(): Converter.Factory {
return GsonConverterFactory.create(createCustomeDataGson())
}
fun <T> createRetrofitService(clazz: Class<T>,
baseUrl: String,
okHttpClient: OkHttpClient): T {
val restAdapter = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(getGsonConverterFactory())
.build()
return restAdapter.create(clazz)
}
最终,改造服务被取消:
fun createCustomeDataApiApi(): CustomeDataApi {
val baseUrl = getBaseUrl(defaultBaseUrl)
return createRetrofitService(CustomeDataApi::class.java, baseUrl, okHttpClient)
}
internal interface CustomeDataApi {
@GET("/api/customedata")
fun getCustomData(@QueryMap params: Map<String, String>?): Call<DataResponse>
}
它以这种方式工作。
但是有些用例没有使用retorfit
并且只有一个json字符串,并且想使用gson.fromJson<T>(jsonString, dataClassType)
,
如何配置gson以通过json中的“类型”生成类?
答案 0 :(得分:0)
找到一个示例here
String responseJson = new String(responseBody); // from the service endpoint
// which format has the response of the server
final TypeToken<ServiceResponse> requestListTypeToken = new
TypeToken<ServiceResponse>() {};
// adding all different container classes with their flag
final RuntimeTypeAdapterFactory<AbstractContainer> typeFactory =
RuntimeTypeAdapterFactory
.of(Animal.class, "type") // Here you specify which is the parent class and what field particularizes the child class.
.registerSubtype(Dog.class, "dog") // if the flag equals the class name, you can skip the second parameter. This is only necessary, when the "type" field does not equal the class name.
.registerSubtype(Cat.class, "cat");
// add the polymorphic specialization
final Gson gson = new
GsonBuilder().registerTypeAdapterFactory(typeFactory).create();
// do the mapping
final ServiceResponse deserializedRequestList = gson.fromJson(responseJson, requestListTypeToken.getType() );
不确定为什么需要gson.fromJson(responseJson, requestListTypeToken.getType() );
,可以通过
gson.fromJson(responseJson, ServiceResponse.class);
?有什么区别?