Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Erro na deserialização

Quero consumir uma outra API de filmes. O Json que ela retorna é o seguinte:

imagem do insomnia ilustrando o retorno da apiOu seja, ela envia dentro de um array. Como não consegui utilizar com o Gson(), vi que em outro curso aqui da Alura, a utilização do Jackson.databind, ai tentei e meu código ficou da seguinte maneira:

   @GetMapping("/now")
    @ResponseStatus(HttpStatus.OK)
    public List<DadosMovieTMDB> dadosMovice () throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(uri + "/discover/movie?include_adult=false&language=pt-br"))
                .method("GET", HttpRequest.BodyPublishers.noBody())
                .header("authorization", apiKey)
                .header("accept", "application/json")
                .build();

        HttpClient client = HttpClient.newHttpClient();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        JsonNode jsonNode = new ObjectMapper().readTree(response.body()).get("results");
        List<DadosMovieTMDB> dadosMoviesList = new ArrayList<>();
        jsonNode.elements().forEachRemaining(movie -> {
            dadosMoviesList.add(new DadosMovieTMDB(
                    movie.get("title").toString(), movie.get("overview").toString(),
                    movie.get("release_date").toString(), movie.get("backdrop_path").toString(),
                    movie.get("vote_average").asDouble()));
        });

        dadosMoviesList.stream().forEach(movie -> System.out.println(movie.toString()));

        return dadosMoviesList;
    }

O problema que estou enfrentando, é que na deserialização as chaves estão vindo com um formato estranho (""), dessa forma:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

1- Gostaria de tirar as aspas de forma que não utilizasse o replace ou substring, pois acredito(não tenho certeza) que utilizar o replace nesse caso, seria uma má prática um vez que deve ter alguma forma melhor para solucionar este problema. 2- Tem um jeito mais profissional de fazer essa requisição ou forma como estou fazendo esta ok?

Qualquer dica de código é sempre bem vinda.

2 respostas

Ei Lucas, eu mexi pouco com Jackson, mas lembro de ter usado muito ObjectMapper pra fazer os mapeamentos de json de forma bem simples. Não consegui identificar rapidamente qual o problema do seu código, mas esse comportamento de adicionar "escapes" e barras geralmente ocorre em conversão de String.

Uma coisa interessante é pegar um response em JSON direto em vez de String, por meio do inputStream

HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());

E sobre o objectMapper, um exemplo de implementacão que você pode testar é esse:

ObjectMapper objectMapper = new ObjectMapper();
    List<DadosMovieTMDB> dadosMoviesList = objectMapper.readValue(response.body(), new TypeReference<List<DadosMovieTMDB>>() {
    });

Enfim, não respondi exatamente as suas questões, mas são alternativas interessantes de explorar.

solução!

Oi Estudante, obrigado por tentar me ajudar. Deixa eu te dar um feedback.

Ao tentar fazer da forma como você me mostrou tive o seguinte erro:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type java.util.ArrayList<br.com.mdroslucas.moviesapi.model.movie.DadosMovieTMDB> from Object value (token JsonToken.START_OBJECT)\n at [Source: (jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream);

E acredito que esse erro foi por que o Json que eu estava recebendo está dentro de um array, então ele não conseguiu deserializar automaticamente para o meu record DadosMovieTMDB.

Não posso afirmar, porque ainda estou aprendendo, mas acredito que o problema fosse o ".toString()". Como ele estava recevendo uma string, o toString tentava convertê-la a uma string novamente criando mais um par de aspas.

Embora ainda não tenha refatorado o código, o problema foi resolvido da seguinte maneira:

        Gson gson = new Gson();

        JsonObject jsonObject = gson.fromJson(response.body(), JsonObject.class);

        JsonArray resultsArray = jsonObject.get("results").getAsJsonArray();

        List<DadosMovieTMDB> dadosMoviesList = new ArrayList<>();

        for (JsonElement movieElement : resultsArray) {
            JsonObject movieObject = movieElement.getAsJsonObject();
            DadosMovieTMDB dadosMovie = new DadosMovieTMDB(
                    movieObject.get("title").getAsString(), movieObject.get("overview").getAsString(),
                    movieObject.get("release_date").getAsString(), movieObject.get("backdrop_path").getAsString(),
                    movieObject.get("vote_average").getAsDouble()
            );
            dadosMoviesList.add(dadosMovie);
        }

Obrigado novamente por tentar ajudar!