Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Solucionado (ver solución)
Solucionado
(ver solución)
8
respuestas

Error al deserializar

Tengo un problema, estoy tratando de realizar la busqueda por id, estoy usando esta API https://stephen-king-api.onrender.com/?ref=public_apis Y esto es lo que tengo para realizar la busqueda

System.out.println("Digite el id del libro que desea buscar");
        var idLibro = scanner.nextLine();
        json = consumoApi.consumirApi(URL_BUSQUEDA + "/" + idLibro);
        var datosBusqueda = convierteDatos.consumirApi(json, Datos.class);
        System.out.println(datosBusqueda);
        Optional <DatosLibros> libroBuscado = datosBusqueda.resultadosLibros().stream()
                .filter(l -> Boolean.parseBoolean(String.valueOf(String.valueOf(l.id()).contains(idLibro))))
                .findFirst();
        if (libroBuscado.isPresent()){
            System.out.println("Libro encontrado");
            System.out.println(libroBuscado.get());
        } else{
            System.out.println("Libro no encontrado");
        }

Y me sale este error

8 respuestas

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type java.util.ArrayList<com.aluracursos.desafioApi.model.DatosLibros> from Object value (token JsonToken.START_OBJECT) at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 9] (through reference chain: com.aluracursos.desafioApi.model.Datos["resultadosLibros"]) at com.aluracursos.desafioApi.service.ConvierteDatos.consumirApi(ConvierteDatos.java:15) ~[classes/:na] at com.aluracursos.desafioApi.principal.Principal.muestraElMenu(Principal.java:45) ~[classes/:na] at com.aluracursos.desafioApi.DesafioApiApplication.run(DesafioApiApplication.java:19) ~[classes/:na] at org.springframework.boot.SpringApplication.lambda$callRunner$5(SpringApplication.java:790) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:83) ~[spring-core-6.1.8.jar:6.1.8] at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[spring-core-6.1.8.jar:6.1.8] at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:88) ~[spring-core-6.1.8.jar:6.1.8] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-3.3.0.jar:3.3.0]

Estuve buscando el error y me dice que puede ser por problemas en la deserialización del JSON, pero no encuentro como solucionar el problema, esto es lo que tengo en el Record Datos

@JsonIgnoreProperties(ignoreUnknown = true)
public record Datos(
       @JsonAlias("data") List <DatosLibros> resultadosLibros
) {

}

Y esto en el datos libros

@JsonIgnoreProperties (ignoreUnknown = true)

public record DatosLibros(
        @JsonAlias ("Title") String titulo,
        @JsonAlias ("id") int id,
        @JsonAlias("villains") List<DatosVillanos> villanos,
        @JsonAlias("Pages") int numeroDePaginas,
        @JsonAlias("Year") int añoLanzamiento

        ) {
}

Ese error me sale solo para busqueda del libro por id, https://stephen-king-api.onrender.com/api/book/19 Pero para buscar todos los libros https://stephen-king-api.onrender.com/api/books si funciona normal

Y el problema es que no me deja entrar ni a la busqueda, esta solo en esta parte

System.out.println("Digite el id del libro que desea buscar");
//        var idLibro = scanner.nextLine();
//        json = consumoApi.consumirApi(URL_BUSQUEDA + "/" + idLibro);
//        var datosBusqueda = convierteDatos.consumirApi(json, Datos.class);
//        System.out.println(datosBusqueda);

Y esta es la url busqueda que uso

private static final String URL_BUSQUEDA = "https://stephen-king-api.onrender.com/api/book";

Hola, posiblemente cuando vas por /books devuelve un arreglo, en cambio cuando vas por el /books/id devuelve un objeto, por lo tanto, si intentas convertir una lista a un record que la contiene será correcto, pero si es un libro individual mandará error ya que no es una lista, si no un objeto.

Si creo que ese es el problema también, pero se solucionaría haciendo un record? o como podría ser, por que la verdad no se como o creando un metodo para que retorne el json solo, y no la clase?

solución!

Si tienes datos libros posiblemente puedas utilizar dicho record con la otra petición, solo que comparando los resultados de la api se distingue que un resultado comienza con un objeto data: [{ que indica una lista y el otro para data: { que indica que contiene un objeto, por tanto es posible que requieras crear un record en el que contenga un objeto similar que en tu clase Datos solo que en lugar de lista ahora será solo un objeto DatosLibro y hacer la conversión respectiva. Ya que en cada resultado siempre esta data: al principio que contiene lo demás, si el objeto de id regresara solamente el objeto { iniciando la llave entonces si sería posible utilizar únicamente tu clase DatosLibros directamente pero en este caso comienza con data: en ambos resultados

Vale, lo probare, muchas gracias