I have this json:
{
"List": [
{
"Field1": 1678493915,
"Field2": "A string"
}
]
}
When I define this method in a helper class:
public static Map<String, List<Map<String, String>>> readJSON(String json) throws JsonProcessingException {
return new ObjectMapper().readValue(json, new TypeReference<>() {});
}
The field Field1
is parsed as a String as I want. But I want to make the method generic enough to be used in other places so I wrote this one in the helper class:
public static <T> T readJSON2(String json) throws JsonProcessingException {
return new ObjectMapper().readValue(json, new TypeReference<>(){});
}
And I called:
Map<String, List<Map<String, String>>> data = readJSON2(jsonString);
Unluckily in this case Field1
is parsed as an Integer.
I can do the following in the helper class:
public static <T> T readJSON3(String json, TypeReference<T> typeReference) throws JsonProcessingException {
return new ObjectMapper().readValue(json, typeReference);
}
And call it in this way:
Map<String, List<Map<String, String>>> data = readJSON3(jsonString, new TypeReference<>(){});
This works (Field1
is being parsed as String), but I would really like to encapsulate all the Jackson stuff like TypeReference in the helper class. This is, I don't want the caller to use TypeReference. Any idea?
Thanks in advance.
Read the article: https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast (paragraph 6). There are the limits to use generic types due to runtime nature.
As I see, you can use solution such as:
public class Program {
private static final ObjectMapper mapper = new ObjectMapper();
public static void main(String[] args) throws IOException {
String json = "{\n" +
" \"List\": [\n" +
" {\n" +
" \"Field1\": 1678493915,\n" +
" \"Field2\": \"A string\"\n" +
" }\n" +
" ]\n" +
"}";
Map<String, List<CustomType>> res = func(json, CollectionCustomType.class);
}
private static <T> T func(String json, Class<T> type) throws IOException {
JavaType javaType = mapper.getTypeFactory().constructType(type);
return mapper.readValue(json, javaType);
}
@Data
private static class CustomType {
@JsonProperty("Field1")
private String field1;
@JsonProperty("Field2")
private String field2;
}
private static class CollectionCustomType extends HashMap<String, List<CustomType>> {}
}