Search code examples
javaspringgenericsobjectmapper

Java ObjectMapper.readValue turns generic type to LinkedHashMap


    @Service
public class PokemonManager implements PokemonService {

    private HttpResponse<String> getStringHttpResponseByUrl(final String url) {
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .GET().header("accept", "application/json")
                .uri(URI.create(url)).build();
        HttpResponse<String> httpResponse = null;
        try {
            httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return httpResponse;
    }

    private <T> T getObjectResponse(T t, String url) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            t = objectMapper.readValue(getStringHttpResponseByUrl(url).body(), new TypeReference<>() {
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return t;
    }

    private List<Pokemon> getAllPokemonsAsList() {

        final String POSTS_API_URL = "https://pokeapi.co/api/v2/pokemon?limit=10000";
        PokeApiResponse pokeApiResponse = new PokeApiResponse();
        pokeApiResponse = getObjectResponse(pokeApiResponse, POSTS_API_URL);
        System.out.println(pokeApiResponse);
        return pokeApiResponse.results;
    }

    @Override
    public List<Pokemon> getAll() {
        return getAllPokemonsAsList();
    }

I have a code as above. If I do not use generics in the "getObjectResponse" method, the code works fine. However, when I use generics, the type of "t" becomes "LinkedHashMap" instead of "PokeApiResponse", and the code crashes. How can I fix this problem?


Solution

  • Generally you would use it:

    objectMapper.readValue("yourJSONHere", PokeApiResponse.class);
    

    If you wanted a Generic T response perhaps this would work

    private <T> T getGeneric(Class<T> clazz, String json) throws IOException {
        return  new ObjectMapper().readValue(json, clazz);
    }
    

    Example:

        Pokemon charmander = getGeneric(Pokemon.class, "{\n" +
                "  \"name\": \"charmander\"\n" +
                "}");