【问题标题】:Java ObjectMapper.readValue turns generic type to LinkedHashMapJava ObjectMapper.readValue 将泛型类型转换为 LinkedHashMap
【发布时间】:2021-09-02 11:01:46
【问题描述】:
    @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();
    }

我有上面的代码。如果我不在“getObjectResponse”方法中使用泛型,则代码可以正常工作。但是,当我使用泛型时,“t”的类型变为“LinkedHashMap”而不是“PokeApiResponse”,并且代码崩溃了。我该如何解决这个问题?

【问题讨论】:

    标签: java spring generics objectmapper


    【解决方案1】:

    通常你会使用它:

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

    如果您想要一个通用 T 响应,也许这会起作用

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

    例子:

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

    【讨论】:

    • 其实我在这个类中有另一个方法,我也想在那个方法中使用这个泛型方法。 PokemonDetails pokemonDetails = new PokemonDetails(); pokemonDetails = getObjectResponse(pokemonDetails, POSTS_API_URL);
    • 适合我
    【解决方案2】:

    您没有为 ObjectMapper 传递足够的信息来以这种方式解析 JSON。也不需要传递响应的实例,您可以使用 Class 代替。我还将提取 json 解析逻辑以分离方法:

        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;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多