как создать Gson для создания различных классов pojo на основе данных строки json, используя gson.fromJson () - PullRequest
0 голосов
/ 03 апреля 2019

При использовании дооснащения для получения 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
    }
]
}

с retofit, это может быть сделано с помощью addConverterFactory с Converter.Factory, например: здесь с RuntimeTypeAdapterFactory он создает dataAdapter для создания Gson и просит создать calsses на основе "type"

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 a Converter. Фабрика создана для модернизации до 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?

1 Ответ

0 голосов
/ 03 апреля 2019

найти образец здесь

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);

? в чем разница?

некоторые ссылки: 1; 2; 3;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...