Saltar a contenido

Ficheros JSON

JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos. Es un fichero fácil de leer y escribir para los humanos y también fácil de analizar y generar para las máquinas. Se basa en un subconjunto del lenguaje de programación JavaScript. Debido a su amplia adopción como alternativa a XML. JSON es un formato de texto que es completamente independiente del lenguaje pero utiliza convenciones que son ampliamente conocidos por los programadores de la familia de lenguajes C, incluyendo C, C++, C#, Java, JavaScript, Perl, Python, y muchos otros. Estas propiedades hacen que JSON sea un lenguaje ideal para el intercambio de datos.

JSON se utiliza hoy en día en cada API web única.

JSON se basa en dos estructuras que son universales; virtualmente todos los lenguajes de programación las soportan de una forma u otra:

  • Una colección de pares de name/value. En varios lenguajes, esto se realiza como un objeto, registro, estructura, diccionario, tabla hash, lista con clave o matriz asociativa.
  • Una lista ordenada de valores. En la mayoría de los lenguajes, esto se realiza como una matriz, vector, lista o secuencia.

Tipos de datos disponibles

  1. Números: Se permiten números negativos y opcionalmente pueden contener parte fraccional separada por puntos. Ejemplo: 123.456
  2. Cadenas: Representan secuencias de cero o más caracteres. Se ponen entre doble comilla y se permiten cadenas de escape. Ejemplo: "Hola"
  3. Booleanos: Representan valores booleanos y pueden tener dos valores: true y false
  4. null: Representan el valor nulo.
  5. Array: Representa una lista ordenada de cero o más valores los cuales pueden ser de cualquier tipo. Los valores se separan por comas y el vector se mete entre corchetes.
  6. Objetos: Son colecciones no ordenadas de pares de la forma nombre:valor separados por comas y puestas entre llaves. El nombre tiene que ser una cadena entre comillas dobles. El valor puede ser de cualquier tipo.

Ejemplo de fichero JSON

{
  "departamentos": [
    {
      "id": 8,
      "nombre": "Ventas",
      "director": "Juan Rodríguez",
      "empleados": [
        {
          "nombre": "Pedro",
          "apellido": "Fernández"
        },
        {
          "nombre": "Jacinto",
          "apellido": "Benavente"
        }
      ]
    },
    {
      "id": 9,
      "nombre": "Recursos Humanos",
      "director": "María Pérez",
      "empleados": [
        {
          "nombre": "Laura",
          "apellido": "González"
        },
        {
          "nombre": "Roberto",
          "apellido": "Martínez"
        }
      ]
    },
    {
      "id": 10,
      "nombre": "Desarrollo",
      "director": "Ana García",
      "empleados": [
        {
          "nombre": "Luis",
          "apellido": "López"
        },
        {
          "nombre": "Elena",
          "apellido": "Sánchez"
        }
      ]
    }
  ]
}

El fichero anterior se puede traducir como un array Departamentos donde cada Departamento:

  • Campos: id, director, empleados
  • empleados: Array de Empleado con campos: nombre, apellido

URL oficial

The JSON Specification

JSON vs XML

JavaIO

Java JSON

Java por defecto no ofrece ninguna funcionalidad integrada para analizar o crear JSON, en lugar de eso, tendremos que confiar en una biblioteca/paquete de terceros.

En la actualidad existen varias librerías para pasar transformar un objeto Java en una cadena JSON (serialización) o viceversa (deserialización).

Desde la página en donde se encuentra la especificación de JSON se indican las librerías más conocidas para tratar/generar información relativa al formato JSON en los diferentes lenguajes de programación.

Librería jackson-databind

Jackson Databind es una biblioteca de Java que forma parte del proyecto Jackson, una de las bibliotecas de código abierto más populares para el procesamiento de JSON en Java. Jackson Databind proporciona funcionalidades para mapear objetos Java a JSON (serialización) y viceversa (deserialización).

Jackson Databind

Agregar librería al proyecto

Para utilizar la librería hay que añadirla al proyecto en intelliJ

json json

json

Nos habrá agregado la librería al proyecto

json

Crea los POJO que correspondan al fichero json

Tenemos que identificar las clases Java que corresponden al json. Por ejemplo,

{
  "noticias": [
    {
      "fecha": "2024-04-26",
      "titulo": "Descubrimiento de nueva especie de planta en la selva amazónica",
      "descripcion": "Investigadores han anunciado el descubrimiento de una nueva especie de planta en la selva amazónica. La planta, que ha sido bautizada como 'Amazoniaensis flore', se caracteriza por sus grandes hojas y flores de vivos colores."
    },
    {
      "fecha": "2024-04-25",
      "titulo": "Avances en la lucha contra el cambio climático",
      "descripcion": "Científicos han publicado un nuevo estudio que revela avances prometedores en la lucha contra el cambio climático. Según el estudio, las medidas de reducción de emisiones implementadas en varios países están comenzando a dar resultados tangibles en la disminución de la concentración de gases de efecto invernadero en la atmósfera."
    }
  ]
}

Tendríamos que crear la clase con la lista de noticias.

public class Noticias {
    private List<Noticia> noticias;

    public List<Noticia> getNoticias() { return noticias; }
    public void setNoticias(List<Noticia> value) { this.noticias = value; }

     @Override
    public String toString() {
        return "Noticias{" +
                "noticias=" + noticias +
                '}';
}

Importante

La clase puede tener varios constructores, pero siempre tiene que tener el constructor por defecto sin parámetros

Una clase para las Noticias

class Noticia {
    private LocalDate fecha;
    private String titulo;

    private String descripcion;
    //es obligatorio este constructor
    public Noticia() {
    }

    public Noticia(String fecha, String titulo, String descripcion) {
        setFecha(fecha);
        this.titulo = titulo;
        this.descripcion = descripcion;
    }

    public String getDescripcion() { return descripcion; }
    public void setDescripcion(String value) { this.descripcion = value; }

    public String getFecha() { return fecha.toString(); }
    public void setFecha(LocalDate value) { this.fecha = value; }
    //no existe el tipo fecha en json
    public void setFecha(String value){
        this.fecha=LocalDate.parse(value);
    }

    public String getTitulo() { return titulo; }
    public void setTitulo(String value) { this.titulo = value; }

    @Override
    public String toString() {
        return "Noticia{" +
                fecha +"\n"+
                titulo+"\n"+
                descripcion+
                "}\n";
    }
}
Para leer el Json y transformarlos a objetos Java, la clase principal es ObjectMapper

public static void main(String[] args) {
    // Lee los datos de un archivo json
    try {

        //Lectura del fichero
        var objectMapper = new ObjectMapper();
        // Convierte el json  en un objeto de tipo Noticias
        Noticias noticias =  objectMapper.readValue(new File("noticias.json"), Noticias.class);
        System.out.println(noticias);

        //Escritura fichero
        //añadimos una nueva noticia
        noticias.getNoticias().add(new Noticia("2024-04-24","Lanzamiento exitoso de la misión espacial a Marte","La agencia espacial internacional ha anunciado el exitoso lanzamiento de una misión espacial con destino a Marte. Esta misión, denominada 'Explorador Rojo', tiene como objetivo buscar signos de vida pasada o presente en el planeta rojo y recopilar datos sobre su geología y atmósfera."));

        //Para que muestre el JSON tabulado
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        // Convertir objeto a un string json
        String jsonString = objectMapper.writeValueAsString(noticias);
        System.out.println(jsonString);

        //Guardar el JSON en un fichero
        objectMapper.writeValue(new File("noticias2.json"), noticias);

    } catch (IOException e) {
        System.out.println("Error E/S: "+e.getMessage());
    } catch (Exception e){
        System.out.println("Error parser json: "+e.getMessage());
    }

}

Plugin de IntelliJ para crear las clases desde un json

IntelliJ tiene varios plugin que permiten crear las clases a partir del Json. Uno de ellos es JsonToJava

Podemos añadir el plugin

json

Una vez añadido(tendrás que reiniciar IntelliJ), podemos crear una primera aproximación a las clases necesarias mediante

json

Insertamos el json de muestra y le damos nombre a la clase superior, en nuestro caso Noticias

json

Nos genera las clases Java necesarias para parsear en Json.

La librería Jackson, tiene muchas utilidades. Debéis consultar la documentación técnica.

Lectura de un servicio Rest

Con esta librería tenemos fácil leer un servicio Web y convertirlo en objetos Java. Por ejemplo, vamos a leer un servicio de ejemplo disponible en la web

jsonplaceholder

Vamos a leer todos los posts disponibles y crear un ArrayList de Posts del servicio Web

https://jsonplaceholder.typicode.com/posts

Primero definimos el POJO para el Post que define la información

class Post {
    private long id;
    private String title;
    private String body;
    private long userId;

    public long getid() { return id; }
    public void setid(long value) { this.id = value; }

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

    public String getBody() { return body; }
    public void setBody(String value) { this.body = value; }

    public long getUserId() { return userId; }
    public void setUserId(long value) { this.userId = value; }

    @Override
    public String toString() {
        return "Post{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", body='" + body + '\'' +
                ", userId=" + userId +
                "}\n";
    }
}

Para solicitar al Web Service todos los Posts es necesario saber que información contiene el JSON, en nuestro caso es una lista de Posts. Creamos un objeto URL con el endpoint y le indicamos a Jackson que queremos una Lista de Posts

 public static void main(String[] args) {
    String url="https://jsonplaceholder.typicode.com/posts";
    List<Post> posts;
    try {
        ObjectMapper objectMapper = new ObjectMapper();
        posts = objectMapper.readValue(new URL(url), new TypeReference<List<Post>>() {});
        System.out.println(posts);

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}