Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 799
Fatih Enes Avatar asked Apr 12 '26 11:04

Fatih Enes


2 Answers

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" +
            "}");
like image 200
JCompetence Avatar answered Apr 15 '26 01:04

JCompetence


You are not passing enough information for ObjectMapper to parse the JSON this way. Also there is no need to pass the instance of response, you can use the Class instead. I would also extract json parsing logic to separate method:

    public static <T> T jsonToModel(String document, Class<T> type) throws IOException {
        return new ObjectMapper().readValue(document, type);
    }

    private List<Pokemon> getAllPokemonsAsList() {
        final String postsApiUrl = "https://pokeapi.co/api/v2/pokemon?limit=10000";
        final HttpResponse<String> httpResponse = getStringHttpResponseByUrl(postsApiUrl);
        final PokeApiResponse pokeApiResponse = jsonToModel(pokeApiResponse, PokeApiResponse.class);
        System.out.println(pokeApiResponse);
        return pokeApiResponse.results;
    }
like image 41
udalmik Avatar answered Apr 15 '26 00:04

udalmik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!