Saltar a contenido

29. JSON

Acrónimo de "Javascruot Object Notation". Es un formato sencillo y alternativo a XML para el intercambio de datos.
Web de referencia: json.org

Algunos características de JSON: * Los analizadores sintácticos para JSON son relativamente sencillos.
* No dispone de procesamiento tipo XSL. * No sustituye a XML y en muchos casos se utiizan conjuntamente. * No está asociado a ningún lenguaje de programación.
* Utilizado con REST API

29.1 Sintaxis

Tipos de datos:
* Numeros * Booleanos * null * Listas/Array * Objeto: colección no ordenado de pares clave-valor

JSON se construye con dos estructuras: * Un diccionario u objeto (es decir una colección no ordenada de pares clave-valor). * Una lisda ordenada de valores.

Ejemplo:

{
  "departamento":8,
  "nombredepto":"Ventas",
  "director": "Juan Rodríguez",
  "empleados":[
    {
      "nombre":"Pedro",
      "apellido":"Fernández"
    },{
      "nombre":"Jacinto",
      "apellido":"Benavente"
    } 
  ]
}

29.2 Definiciones de sintáxis JSON

29.2.1 OBJETO

objeto

29.2.2 ARRAY

Colección de valores (value )

array

29.2.3 VALUES

value

29.2.4 STRING

Uno o más carácteres UNICODE.

string

29.2.5 NUMBER

number

29.2.6 WHITESPACE

whitespace

29.3 Uso JSON para intercambio de datos. JSCRIPT

Usando el API Fetch vamos a ver algunos ejemplos.

Este api permite manipular las peticiones y respuestas HTTP.
Nos fijamos en uno de sus métodos globales: fectch() que facilita la obtención de respuestas http en forma asíncrona.
Con anterioridad para estas funciones se utilizaba ( y se sigue usando) el método XMLHttpRequest.

Debemos tener en cuenta para el método fetch: * El objeto Promise devuelto nunca se rechaza (incluyendo el caso de error 404, etc * Por defecto fetch no usa cookies.

Ejemplo:

fetch('http://example.com/movies.json')
  .then(response => response.json())
  .then(data => console.log(data));

29.3.1 Comprobación de la respuesta.

fetch('flores.jpg').then(function(response) {
  if(response.ok) {
    response.blob().then(function(miBlob) {
      var objectURL = URL.createObjectURL(miBlob);
      miImagen.src = objectURL;
    });
  } else {
    console.log('Respuesta de red OK pero respuesta HTTP no OK');
  }
})
.catch(function(error) {
  console.log('Hubo un problema con la petición Fetch:' + error.message);
});

29.3.2 Webs abiertas para REST-API con json.

Las siguientes web son servidores que se pueden usar para probar rest-api.

  • https://pokeapi.co/
  • https://api.chucknorris.io/
  • https://rickandmortyapi.com/
  • https://www.thecocktaildb.com/api.php
  • https://randomuser.me/
  • https://www.themoviedb.org/ (necesita registrarse)
  • https://themealdb.com/api.php

29.3.3 Ejemplo

Usando la url: https://www.thecocktaildb.com/api/json/v1/1/search.php?f=a

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cocktail API Example</title>
    <style>
        ul {
            list-style-type: none;
        }
        li {
            padding: 10px;
            border-bottom: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <h1>Cocktails</h1>
    <button id="fetchData">Fetch Data</button>
    <ul id="cocktailList"></ul>

    <script>
        const fetchDataButton = document.getElementById('fetchData');
        const cocktailList = document.getElementById('cocktailList');

        fetchDataButton.addEventListener('click', () => {
            fetch('https://www.thecocktaildb.com/api/json/v1/1/search.php?f=a')
                .then(response => response.json())
                .then(data => {
                    cocktailList.innerHTML = '';
                    data.drinks.forEach(drink => {
                        const listItem = document.createElement('li');
                        listItem.innerText = `${drink.strDrink} - ${drink.strInstructions}`;
                        cocktailList.appendChild(listItem);
                    });
                })
                .catch(error => {
                    console.error('Error fetching data:', error);
                });
        });
    </script>
</body>
</html>

29.3.4 Con objeto Request propio.

En la llamada a fetch en lugar del url podemos pasar un objeto Request() como argumento.

  ddvar myHeaders = new Headers();

var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };

var myRequest = new Request('flowers.jpg', myInit);

fetch(myRequest)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});  

29.3.5 Enviar petición con credenciales include

29.3.6 Enviar datos con JSON

var url = 'https://example.com/profile';
var data = {username: 'example'};

fetch(url, {
  method: 'POST', // or 'PUT'
  body: JSON.stringify(data), // data can be `string` or {object}!
  headers:{
    'Content-Type': 'application/json'
  }
}).then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));

29.4 Librería GSON para JAVA

Desarrollada por Google para Java. Guía completa
Serializamos primitivas y objetos java a json y viceversa (deserializar)

Algunas consideraciones:

  • Todos los campos de la clase y de su superclase se incluyen en la serialización
  • Podemos excluir campos mediante anotaciones.
  • If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.
    *This implementation handles nulls correctly
  • While serialization, a null field is skipped from the output
  • While deserialization, a missing entry in JSON results in setting the corresponding field in the object to null
  • If a field is synthetic, it is ignored and not included in JSON serialization or deserialization
  • Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization

29.4.1 Serialziar/Deserializar colecciones con un número de tipos arbitrario

Por ejemplo:

['hello',5,{name:'GREETINGS',source:'guest'}]
Que equivale a la colección :
Collection collection = new ArrayList();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));
//Where the Event class is defined as:
class Event {
  private String name;
  private String source;
  private Event(String name, String source) {
    this.name = name;
    this.source = source;
  }
}
La serialización la realiza gson automáticamente. El camino inverso no es posible sin ayuda. Tres soluciones: * Usar gson parse api de bajo nivel. Encontramos ejemplos en : github gson
* Registrar un adaptador de tipo para "Collection.class" * Registrar un adaptador de tipo para for MyCollectionMemberType and use fromJson with Collection This approach is practical only if the array appears as a top-level element or if you can change the field type holding the collection to be of type Collection.

29.5 Servidor para pruebas

Disponible y abierto en jsonplaceholder

Ejemplo para empezar:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))