The problem
We are save configuration elements to Dynamodb: the key is the configuration name, the value is the JSON string.
Recently I am trying to refactor the code to make the service code much shorter and easier to read. But I made one mistake - related with Java Type erasure.
The following code tries to read configuration: its value is a Map. I want to create one generic method that can read different Map.
The Solution
We have to specify class type like below:
Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure
Jackson Date Serialize + Deserialize
Apache Commons TypeLiteral
Google Guice TypeLiteral
Effects of Type Erasure and Bridge Methods
We are save configuration elements to Dynamodb: the key is the configuration name, the value is the JSON string.
Recently I am trying to refactor the code to make the service code much shorter and easier to read. But I made one mistake - related with Java Type erasure.
The following code tries to read configuration: its value is a Map
@Nonnull
private <T> Map<String, T> getMapConfig(final String configName) {
final ConfigElement c = configDao.getConfigByName(configName);
Map<String, T> resultMap = null;
if (c != null) {
String json = c.getValue();
resultMap = objectMapper.readValue(json, new TypeReference<Map<String, T>>() {});
}
if (resultMap == null) {
resultMap = new HashMap<>();
}
return resultMap;
}
private <T> T convertMapValue(final String json) {
return objectMapper.readValue(json, new TypeReference<T>(){});
}
But this doesn't work: because of type erasure, T is just a type variable, at runtime, Java can't get the real value of the type.The Solution
We have to specify class type like below:
@Nonnull
private <T> Map<String, T> getMapConfig(final String configName, final Class<T> classType) {
final ConfigElement c = configDao.getConfigByName(configName);
Map<String, T> resultMap = null;
if (c != null) {
String json = c.getValue();
final MapType mapType = TypeFactory.defaultInstance().constructMapType(Map.class, String.class, classType);
resultMap = objectMapper.readValue(json, mapType);
}
if (resultMap == null) {
resultMap = new HashMap<>();
}
return resultMap;
}
private <T> T convertMapValue(final String json,final Class<T> valueType) {
return objectMapper.readValue(json, valueType);
}
One related stuff I found is that in eclipse you can change Eclipse's Warning settings so that if Eclipse will show warnings if some parameter are not used: Change -> Window/Preferences /Java/Compiler/ErrorsWarnings -> Unnecessary Code > Value of parameter is not used to warning.Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure
Jackson Date Serialize + Deserialize
Apache Commons TypeLiteral
Google Guice TypeLiteral
Effects of Type Erasure and Bridge Methods