No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Adquiere por un a帽o todos los cursos, escuelas y certificados por un precio especial.

Antes: $249

Currency
$219/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Comprar ahora

Termina en:

0D
6H
25M
46S

Mostrar datos de la API en la aplicaci贸n

19/25
Recursos

Aportes 42

Preguntas 7

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Si llegaron al final de este video y no les muestra la imagen del gato y encima les sale un error como este: "Can鈥檛 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(鈥淯ser-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(鈥淕ET鈥, 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);
    }
      
    
}`

Profesor, el error de Can鈥檛 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茅.


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/

Si les da el error:

method GET must not have a request body

cambien el .method(鈥淕ET鈥, body) por .get()

        Request request = new Request.Builder()
                .url("https://api.thecatapi.com/v1/images/search")
                .get()
                .build();

Estudiantes, actualic茅 el proyecto en mi repositorio aplicando mejores pr谩cticas

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.

Salioooooo

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/)

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.

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

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 馃槂

Esta clase la tuve que ver dos veces jaja pero muy bueno

Lo estoy haciendo en Intellij y estaba luchando con correrlo porque me salia el error 鈥淐an鈥檛 get input strea from URL!鈥.
Finalmente corrio cuando el IDE me llevo a hacer un scratch.java

import java.io.IOException;
class Scratch {
    public static void main(String[] args) throws IOException {
        GatosService.verGatos();
    }
}

y el aporte del codigo de importar la imagen

Image image = 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) {

Ha cambiado un poco la respuesta de la API desde que se sac贸 el curso. Aqui mi solucion (si eliminas el break de despues del switch se convierte en un bucle de gatos infinito xD):

package com.cats_api;

import java.awt.Image;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import com.google.gson.Gson;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

public class CatsService {

	public static void showCats() throws IOException {
		// Crear un cliente HTTP para realizar solicitudes a la API
		OkHttpClient client = new OkHttpClient();

		// Construir la solicitud HTTP GET con la URL de la API y el cuerpo de la
		// solicitud
		Request request = new Request.Builder().url("https://api.thecatapi.com/v1/images/search?limit=10").get()
				.build();

		// Ejecutar la solicitud HTTP y obtener la respuesta
		Response response = client.newCall(request).execute();

		// Extraer la respuesta en formato JSON como String
		String respJSON = response.body().string();

		// Imprimir la respuesta JSON en la consola
		System.out.println(respJSON);

		// Crear un objeto Gson para manejar la serializaci贸n/deserializaci贸n de JSON
		Gson gson = new Gson();

		// Deserializar la respuesta JSON a un array de objetos Cats
		Cats[] catsArray = gson.fromJson(respJSON, Cats[].class);

		for (Cats cats : catsArray) {

			// Crear una variable para almacenar la imagen
			Image img = null;

			try {
				// Crear un objeto URL a partir de la URL de la imagen en la respuesta JSON
				URL url = new URL(cats.getUrl());

				// Leer la imagen desde la URL
				img = ImageIO.read(url);

				// Crear un ImageIcon con la imagen obtenida
				ImageIcon catBackground = new ImageIcon(img);

				// Si el ancho de la imagen es mayor a 800, redimensionarla
				if (catBackground.getIconWidth() > 800) {
					Image background = catBackground.getImage();
					Image newBackground = background.getScaledInstance(800, 600, java.awt.Image.SCALE_SMOOTH);
					catBackground = new ImageIcon(newBackground);
				}

				String menu = "Opciones:\n" + "1- Ver otra imagen\n" + "2- Favoritos\n" + "3- Volver";

				String[] botones = { "ver otra imagen", "favoritos", "volver" };

				String idCat = cats.getId();

				String opcion = (String) JOptionPane.showInputDialog(null, menu, idCat, JOptionPane.INFORMATION_MESSAGE,
						catBackground, 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:
					showCats();
					break;
				case 1:
					favoriteCat(cats);
					break;
				case 2:
					break;
				default:
					System.out.println("Opcion no valida");
					break;
				}
				break;

			} catch (Exception e) {
				// Imprimir un mensaje de error si hay alg煤n problema al formatear la imagen
				System.out.println("Error al formatear imagen");
			}
		}
	}

	public static void favoriteCat(Cats cat) {

	}
} 

No esperen que todo les salga perfecto a la primera, tambien hay que leer los comentarios de los compa帽eros he ir probando el c贸digo por nuestra cuenta y haciendo Debug para entender y identificar los errores en la l铆neas especificas. antes de implementar el men煤 hice pruebas, y con el apoyo de los comentarios fui corrigiendo los errores que se tenia. as铆 me quedo la clase GatosService:

<public class GatosService {
    
    public static void verGatos() throws IOException {
        
        // Traemos los datos de la Api dados por postman
        
        OkHttpClient client = new OkHttpClient();
        // MediaType mediaType = MediaType.parse("text/plain");
        // RequestBody body = RequestBody.create(mediaType, "");
        Request request = new Request.Builder()
          .url("https://api.thecatapi.com/v1/images/search")
          .get()
          .build();
        Response response = client.newCall(request).execute();
        
        String elJson = response.body().string(); 
        
        // devemos cortar los primeros corchetes de iteracion del archivo
        elJson = elJson.substring(1, elJson.length()); // corte el primer corteche
        elJson = elJson.substring(0, elJson.length()-1); // corto el ultimo corchete
        
        // creo el objeto de la Gson
        Gson gson = new Gson(); 
        
        // Apartir del gson, creo el objeto gato
        Gatos gatos = gson.fromJson(elJson, Gatos.class); 
        
        // Redimencinar Imagen 
        
        Image image = null;
        
        try {
            URL url = new URL(gatos.getUrl());
            //Creo una conexi贸n HTTP con el servidor que aloja la imagen del perro
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            // Agrega una propiedad de solicitud al objeto http
            http.addRequestProperty("User-Agent", "");
            BufferedImage bufferedImage = ImageIO.read(http.getInputStream());
            ImageIcon fondoGato = new ImageIcon(bufferedImage); 
            
            if (fondoGato.getIconWidth() > 800 || fondoGato.getIconHeight() > 500) {
                
                // redimencionar
                Image fondo = fondoGato.getImage();
                Image modificada = fondo.getScaledInstance(800, 500, java.awt.Image.SCALE_SMOOTH); 
                fondoGato = new ImageIcon(modificada);
            }

            String id_gato = gatos.getId();
            String opcion = (String) JOptionPane.showInputDialog(null, null, id_gato, JOptionPane.INFORMATION_MESSAGE, fondoGato,null, null);
            
            
        } catch (IOException e) {
            
            System.out.println(e);
        }
    }
    
}> 

A mi se me ocurrio la 鈥済enial鈥 idea de usar otra api, pense q seria tan facil como cambiar nombres a atributos y demas, pero esta API que usa el profe devuelve un Json simple, pero q pasa cuando recibimos un arreglo de JSON? o cuando uno de los atributos de JSON tiene sub atributos?

Bueno me di a la tarea de investigar mas de Gson y en particular de la funcion fromJson y encontre este articulo q lo explica muy simple , que espera recibir y que espera dar y ademas explica otra funcion muy util toJson.

Pero aun falta la respuesta a la preguna y si la API devuelve un arreglo de Json o si un atributo tiene subatributos y aqui esta el otro articulo que me ayudo, basicamente para los arreglos pues tiene q haber un atributo en tu clase que sea de tipo List o derivado y para los sub atributos pues hay que crear otra clase que los contenga

Espero q esta informacion te sea de utilidad y me disculpo por la ortografia y redaccion, es tarde y me voy a desmayar XD.

este video fue un desastre鈥!!

Na hasta dejo el curso.
La verdad no entiendo nada. me marca error el codigo no es el mismo y la unica solucion es copiar y pegar pero sin entender que haces mal y que haces bien.
Creo que el back no va a ser para mi, sinceramente hasta 5 videos atras venia super bien pero ya simplemente no entiendo y no creo que sea mi culpa aun que tal vez si.

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.

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鈥檛 get input stream from URL!

Me sale el error de Can鈥檛 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);
    }

}

Explicaci贸n del siguiente c贸digo(el cual fue de ayuda en los comentario de la comunidad), para mostrar las imag茅nes.

new URL(perros.getUrl());
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.addRequestProperty("User-Agent", "");
BufferedImage bufferedImage = ImageIO.read(http.getInputStream());
ImageIcon fondoPerrito = new ImageIcon(bufferedImage);
  • URL url = new URL(perros.getUrl()): Crea un objeto URL a partir de una cadena de texto que representa la direcci贸n URL de una imagen de un perro. Se asume que perros es un objeto que tiene un m茅todo getUrl() que devuelve la cadena de texto de la direcci贸n URL.

  • HttpURLConnection http = (HttpURLConnection) url.openConnection(): Crea una conexi贸n HTTP con el servidor que aloja la imagen del perro. La conexi贸n se establece utilizando la URL creada anteriormente. Se utiliza el m茅todo openConnection() para crear la conexi贸n y se devuelve un objeto de tipo HttpURLConnection. Es necesario hacer un casting a HttpURLConnection porque el m茅todo openConnection() devuelve un objeto de tipo URLConnection, que es la clase padre de HttpURLConnection.

  • http.addRequestProperty(鈥淯ser-Agent鈥, 鈥溾): Agrega una propiedad de solicitud al objeto http. En este caso, se agrega una propiedad que indica el User-Agent de la solicitud HTTP. El User-Agent es una cadena de texto que identifica el tipo de navegador o aplicaci贸n que se est谩 utilizando para realizar la solicitud. En este caso, se establece en una cadena vac铆a, lo que indica que no se proporciona ninguna informaci贸n sobre el User-Agent.

  • BufferedImage bufferedImage = ImageIO.read(http.getInputStream()): Lee la imagen del perro desde la entrada de la conexi贸n HTTP y la almacena en un objeto BufferedImage. La clase ImageIO proporciona m茅todos para leer y escribir im谩genes en varios formatos. En este caso, se utiliza el m茅todo read() para leer la imagen desde la entrada de la conexi贸n HTTP y almacenarla en un objeto `BufferedImage

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.