No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Mostrar datos de la API en la aplicación

19/25
Recursos

Aportes 33

Preguntas 6

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Si llegaron al final de este video y no les muestra la imagen del gato y encima les sale un error como este: "Can’t get input stream from URL! "
Relájense, el error es básicamente por temas de seguridad ya que la imagen está en https y el sitio del api de gatitos no permite la descarga.
El código:
image = ImageIO.read(url);
ImageIcon fondoG = new ImageIcon(image);

Si funciona en http o https que no impida la descarga de la imagen (lo probé), una simple declaración de ulr no es suficiente para descargar la imagen protegida.
Esto me funcionó:
HttpURLConnection httpcon = (HttpURLConnection)url.openConnection();
httpcon.addRequestProperty(“User-Agent”, “”);
BufferedImage bufferedImage = ImageIO.read(httpcon.getInputStream());
ImageIcon fondoG = new ImageIcon(bufferedImage);

Creditos a un usuario de la siguiente clase.
Saludos!

Este es el codigo entero con la solucion del error Input Stream
`public static void verGatitos() throws IOException{
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(“https://api.thecatapi.com/v1/images/search”)
.method(“GET”, null)
.build();
Response response = client.newCall(request).execute();

    String json = response.body().string();
    json = json.substring(1,json.length()-1);
    
    Gson gson = new Gson(); 
    Gatos gatos = gson.fromJson(json, Gatos.class);
    
    Image imagen = null;
    try{
        URL url = new URL(gatos.getUrl());
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        http.addRequestProperty("User-Agent", "");
        BufferedImage bufferedImage = ImageIO.read(http.getInputStream());
        ImageIcon fondoGato = new ImageIcon(bufferedImage);
        
        if(fondoGato.getIconWidth() > 800 || fondoGato.getIconHeight() > 400){
            
            Image fondo = fondoGato.getImage();
            Image modificada = fondo.getScaledInstance(800, 400, java.awt.Image.SCALE_SMOOTH);
            fondoGato = new ImageIcon(modificada);
        }   
            
        String menu =  "Opciones: \n1.- Cambiar Gatitos \n2.-Favorito \n3.-Volver ";
        String botones[] = { "Ver Otra imagen", "Favoritos", "Volver"};
        String id_gato = gatos.getID();
        String opcion = (String) JOptionPane.showInputDialog(null,menu,id_gato,JOptionPane.INFORMATION_MESSAGE
                ,fondoGato,botones,botones[0]);
        
        int seleccion = -1;
        
        for(int i = 0; i < botones.length;i++){
            if(opcion.equals(botones[i])){
                seleccion = i;
            }
        }
        
        switch(seleccion){
            case 0:
                verGatitos();
                break;
            case 1:
                favoritos(gatos);
                break;
            default:
                break;             
        }
        
    }catch(IOException e){
        System.out.println(e);
    }
      
    
}`


Creo que la API de gatitos esta experimentando problemas, asi que utilice una API de perritos les dejo el link:
https://dog.ceo/dog-api/

Profesor, el error de Can’t get input stream from URL! logre solucionarlo gracias al código que compartieron mas abajo que va debajo de la instancia del URL y antes del ImageIcon


HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.addRequestProperty("User-Agent", "");
BufferedImage bufferedImage = ImageIO.read(http.getInputStream());


investigue en Internet pero poco he encontrado, para los que sepan ingles, tengan el mismo error aquí algunas paginas que pueden aclararles un poco

https://www.programcreek.com/java-api-examples/?class=java.net.HttpURLConnection&method=addRequestProperty

https://www.codejava.net/java-se/networking/how-to-use-java-urlconnection-and-httpurlconnection

ahora podre seguir con el tutorial, pero, si no es mucho pedir, alguien podría explicar ese pedacito de código? o el por que algunos les funciona sin ese código y a otros no? Gracias, seguiré investigando si tengo la respuesta la compartiré.

Hola, para los que les das error al ejecutar deberían copiar exactamente la misma dirección que usa Santiago. A mi solo con esa me funcionó.
Aquí se las dejo: https://api.thecatapi.com/v1/images/search

Quien quiere ver gatos? lo de hoy son los memes, les dejo un proyecto en github que busca memes en reddit y devuelve un JSON con la información, este es el link de la API https://meme-api.herokuapp.com/gimme

Este es mi codigo:
MemeService

public class MemesService {
    public static void verMemes() throws IOException {
        ArrayList<String> options = new ArrayList<>();
        options.add(" 1. ver otro meme");
        options.add(" 2. abrir meme en chrome");
        options.add(" 3. favoritos");
        options.add(" 4. volver al menu");
        int op = -1;
        do {
            Meme meme = getMemeFromAPI();
            Object input = JOptionPane.showInputDialog(null, "Opciones: ", meme.getTitle()+" subreddit: "+meme.getSubreddit(), JOptionPane.INFORMATION_MESSAGE, getImageFromURL(meme.getUrl()), options.toArray(), options.get(0));
            op = options.indexOf(input);
//abre el meme en el navegador chrome
            if(op == 1) Runtime.getRuntime().exec(new String[]{"cmd", "/c","start chrome "+meme.getPostLink()});
        }while(op != 3);
    }

    private static Icon getImageFromURL(String url) throws IOException, MalformedURLException {
        return new ImageIcon(ImageIO.read(new URL(url)).getScaledInstance(800,800, BufferedImage.SCALE_SMOOTH));
    }

    private static Meme getMemeFromAPI() {
        Unirest.setTimeouts(0, 0);
        Meme meme = new Meme();
        try {
            HttpResponse<String> response = Unirest.get("https://meme-api.herokuapp.com/gimme")
                    .asString();
             meme = new Gson().fromJson(response.getBody(), Meme.class);
        } catch (UnirestException e) {
            e.printStackTrace();
        }
        return meme;
    }
}

Clase Meme

public class Meme {
    private String url;
    private String postLink;
    private String subreddit;
    private String title;
    //private final String apiKey= "";

    public Meme() {}

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPostLink() {
        return postLink;
    }

    public void setPostLink(String postLink) {
        this.postLink = postLink;
    }

    public String getSubreddit() {
        return subreddit;
    }

    public void setSubreddit(String subreddit) {
        this.subreddit = subreddit;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

Estudiantes, actualicé el proyecto en mi repositorio aplicando mejores prácticas

tengo un problema cuando corre el siguiente fragmento de codigo

<URL url = new URL(gatos.getUrl()); image = ImageIO.read(url);>

image viene como null. Probé utilizando openStream() pero me salta error 403.

<image = ImageIO.read(url.openStream());>

java.io.IOException: Server returned HTTP response code: 403 for URL: https://cdn2.thecatapi.com/images/0KUWJZPjy.jpg

A alguien le paso lo mismo? busque, pero todavía no encontré solución.

Cuidado con la versión del okio que utilizan, yo había descargado 2.2.2 y me estaba dando error, cambié a 1.6.0 para que funcionara

Listo, muy bien para algo introductorio, vamos mejorando

Tiene un error grave de llamado recursivo en el método verGato

Super 😃

si les sale el siguiente error:

Exception in thread "main" java.lang.NoClassDefFoundError: okio/Buffer

Eliminen todas las dependencias, y instalen específicamente las mencionadas 2 clases

En caso les salga el error " Failed to invoke public com.platzi.gatos_app.Gatos()" , deben tener un constructor con parámetros en esa Clase.

Salioooooo

obtengo esta excepción

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:198)
	at java.base/sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1969)

Por que en clases anteriores era un misterio la apikey y acá si la muestran?

Se debería o no mantener confidencial?

Estupenda clase instructor Santiago, acá dejo una imagen de como se ve en la que yo estoy realizando:
 
 

se complica la cosa, gracias profe

Estimados… tengo este incoveniente:
javax.imageio.IIOException: Can’t get input stream from URL!

Me sale el error de Can’t get input stream from URL! logre solucionarlo gracias al código que compartieron. Tendre que haberiguar que hace exactamente cada linea de código, porque fue eficaz.

Puedo correrlo en VSC en vez de netBeans?
NetBeans tuve ciertos problemas ya que no me queria agregar la clase dentro del paquete, si no por serparado por eso intento hacerlo por VSC, peroooo no me agarra el llamado de la API.


Luego de mucho tiempo analizando el codigo me salió!! Y asi me quedó

Funciono perfectamente.

Decidí implementar la clase GatosService de la siguiente manera:

public class CatService {

    private static String consultCat() throws IOException{
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://api.thecatapi.com/v1/images/search")
                .method("GET", null)
                .build();
        return client.newCall(request).execute().body().string();
    }

    public static void verGatos() throws IOException {
        String[] menuButtons = {"Ver otra imagen", "Favorito", "Volver"};
        String jsonRequest = consultCat();
        Cat cat = fromJsonRequestToGato(jsonRequest);
        ImageIcon menuIcon = GetAndResizeCatImage (cat);

        int selection = catsMenu(cat, menuIcon, menuButtons);

        switch (selection) {
            case 0:
                verGatos();
                break;
            case 1:
                System.out.println("Hola, soy la opción 2");
                break;
            case 2:
                System.out.println("Hola, soy la opción 3");
                break;
            default:
                System.out.println("Default option");
            break;
        }

    }

    public static int catsMenu(Cat cat, ImageIcon menuIcon, String[] buttons) {

        int selection = -1;
        String menu = "Opciones:\n" + String.join("\n", buttons);
        String idCat = cat.getId();

        String optionSelected = (String) JOptionPane.showInputDialog(
                null,
                menu,
                idCat,
                JOptionPane.INFORMATION_MESSAGE,
                menuIcon,
                buttons,
                buttons[0]);

        for (int i = 0; i < buttons.length; i++) {
            if (optionSelected.equals(buttons[i])) {
                selection = i;
            }
        }
        return selection;
    }

    public static ImageIcon GetAndResizeCatImage (Cat cat) {
        //Redimensionar la imagen en caso de necesitarlo
        Image image = null;
        ImageIcon menuIcon = null;
        try {
            URL url = new URL(cat.getUrl());
            HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection.addRequestProperty("User-agent","");

            image = ImageIO.read(httpConnection.getInputStream());

            menuIcon = new ImageIcon(image);

            if (menuIcon.getIconWidth() > 800) {
                //Redimensionamos la imagen
                Image fondoRedimensionado = menuIcon
                        .getImage()
                        .getScaledInstance(300, 100, Image.SCALE_DEFAULT);

                menuIcon = new ImageIcon(fondoRedimensionado);
            }
        } catch (IOException e) {
            System.out.println("Error al obtener la imagen--> " + e.getMessage());
        }
        return menuIcon;
    }

    public static Cat fromJsonRequestToGato (String jsonRequest) {
        Gson gson = new Gson();
        //Cortar los corchetes de inicio y fin de la petición
        jsonRequest = jsonRequest.substring(1, jsonRequest.length() - 1);
        return gson.fromJson(jsonRequest, Cat.class);
    }

}

Después de luchar porque tenia un error, era cuestión de solo leer la documentación y vi el porque rápido. Logre este producto final.

Compañeros conseguí la explicación del código que compartieron para los que les causaba el error de la URL.

[Explicacion del objeto HttpUrlConnection] (https://como-programar.net/en-android/httpurlconnection/)

Excelente!

Todo bien hasta el momento, no tuve errores.

Para el caso de la imagen, solo se esta controlando el ancho, también debería validarse la altura.
if(fondoGato.getIconWidth() > 800 || fondoGato.getIconHeight()>1200){


}

O todo caso le ponen un tamaño fijo para que todas las imagenes tengan el mismo tamaño.
Image fondoModificado = fondo.getScaledInstance(600, 600, java.awt.Image.SCALE_SMOOTH);

Aquí quiero decir que es una mala práctica de código colocar código dentro de un try, en general una función debe tener sólo una tarea, el try tiene la tarea de únicamente evaluar si se puede hacer algo sin que suceda un error, así que dentro debería ir únicamente lo que activa ese error.