I have an http endpoint that returns different type of json say Car, Bike, Truck. The structure of JSON is following, It is very much similar for each class
{
"Rows": [
{
"key1": "val1",
"key2": "val2",
}
]
}
I want to write a generic method that creates the list object (Car, Bike, Truck) based on type parameter, (I have all pojo created with proper jackson bindings and they extend Vehicle class)
I came up with following but it is throwing exception at runtime
static <T extends Vehicle> List<T> getTiles(String vehicleName, Class<T> concreteClass) throws IOException {
Map<String, String> queryParamMap = new HashMap<>();
queryParamMap.put("apiKey", "<KEY>");
queryParamMap.put("type", vehicleName);
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
OkHttpClient client = new OkHttpClient();
HttpUrl.Builder builder = new HttpUrl.Builder()
.scheme("https")
.host("<URL>")
.addPathSegment("1");
queryParamMap.entrySet().stream().forEach(k -> builder.addQueryParameter(k.getKey(), k.getValue()));
HttpUrl url = builder.build();
Request request = new Request.Builder()
.addHeader("accept", "application/json")
.url(url).build();
Response response = client.newCall(request).execute();
Map<String, List<T>> m = mapper.readValue(response.body().string(),
new TypeReference<Map<String, List<T>>>() {
});
return m.get("Rows");
}
And I am calling it like
List<Car> cars = Utils.getTiles("CAR", Car.class);
I get the following exception
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.models.Vehicle` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
I know that this is related to type-erasure, as at runtime T gets bound to Vehicle not Car.
How do I solve this ?